<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Referenz vs. lokale Kopie]]></title><description><![CDATA[<p>MahlZeit!</p>
<p>Ich sitze momentan an einem C++ Software Projekt und habe eine grundlegende Frage, die hoffentlich von einem erfahrenen Programmierer schnell beantwortet werden kann.<br />
Es geht um die Frage was schneller ist, einer Funktion eine Referenz zu uebergeben und mit dieser zu arbeiten oder eine lokale Kopie zu erstellen und am Ende der Referenz den Inhalt zuzuweisen.</p>
<p>Durch folgenden Code wurde das ausprobiert und im grossen Umfang getestet. multiply ist eine Member-Funktion von MontgRep. Der Datentyp &quot;MontgRep&quot; besteht aus einem plus- und einem minus-Teil, die jeweils Datentyp vec_ZZ_p ( Vektoren ) sind.</p>
<pre><code>void multiply(MontgRep &amp;a, const  int &amp;A_temp) {
            vec_ZZ_p thevecp,thevecm; // das sind spezielle Vektoren
            thevecp.SetLength(plus.length());
            thevecm.SetLength(plus.length());

            for (int i=plus.length()-1; i&gt;=0; i--) {
                thevecp[i] = a.plus[i]*A_temp;
                thevecm[i] = a.minus[i]*A_temp;
            }
            plus=thevecp;
            minus=thevecm;
}
</code></pre>
<p>Im Gegensatz zu</p>
<pre><code>void multiply(MontgRep &amp;a, const int &amp;B_temp) {
//Folgender Code geht auch ist aber langsamer!!!!!

             for (int i=plus.length()-1; i&gt;=0;  i--) {
                plus[i] = a.plus[i] * B_temp;
                minus[i] = a.minus[i] * B_temp;
            }
        }
</code></pre>
<p><strong>Eigentlich</strong> dachte ich, dass es fuer solch grundlegende Sachen zu viel Aufwand ist, noch zusaetzlich lokale Objekte zu erstellen ( auch wenn sie nicht so gross sind ), wenn man schon Speicher fuer das referenzierte Objekt zur Verfuegung hat, welchen man doch auch nutzen kann ( mir wurde sogar mal geraten, dass man den auch nutzen sollte ).<br />
<strong>Aber</strong> es hat sich herausgestellt, dass das Arbeiten mit einer erstellten einer Kopie und abschliessendem Zuweisen der Werte auf das referenzierte Objekt schneller geht!?</p>
<p>Dieses wurde dann versucht auf andere Funktionen anzuwenden, jedoch mit unterschiedlichem Erfolg, sprich es wurde an anderer Stelle mit <strong>voellig aequivalenter Herangehensweise</strong> langsamer.</p>
<p>Das richt in meiner Nase nach einer speziellen Benutzung von Referenzen. Da diese mir einfach noch nicht bekannt ist, hoffe auf diesem Wege einen Rat zu bekommen.</p>
<p>Hinweise auf Buecher, die das gut umschreiben, werden natuerlich auch dankend angemommen, falls jemand damit dienen kann ... !</p>
<p>Ueber Reaktionen waere ich natuerlich sehr dankbar!</p>
<p>MfG<br />
#50</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/155692/referenz-vs-lokale-kopie</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 19:42:45 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/155692.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 08 Aug 2006 16:46:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Referenz vs. lokale Kopie on Tue, 08 Aug 2006 16:46:34 GMT]]></title><description><![CDATA[<p>MahlZeit!</p>
<p>Ich sitze momentan an einem C++ Software Projekt und habe eine grundlegende Frage, die hoffentlich von einem erfahrenen Programmierer schnell beantwortet werden kann.<br />
Es geht um die Frage was schneller ist, einer Funktion eine Referenz zu uebergeben und mit dieser zu arbeiten oder eine lokale Kopie zu erstellen und am Ende der Referenz den Inhalt zuzuweisen.</p>
<p>Durch folgenden Code wurde das ausprobiert und im grossen Umfang getestet. multiply ist eine Member-Funktion von MontgRep. Der Datentyp &quot;MontgRep&quot; besteht aus einem plus- und einem minus-Teil, die jeweils Datentyp vec_ZZ_p ( Vektoren ) sind.</p>
<pre><code>void multiply(MontgRep &amp;a, const  int &amp;A_temp) {
            vec_ZZ_p thevecp,thevecm; // das sind spezielle Vektoren
            thevecp.SetLength(plus.length());
            thevecm.SetLength(plus.length());

            for (int i=plus.length()-1; i&gt;=0; i--) {
                thevecp[i] = a.plus[i]*A_temp;
                thevecm[i] = a.minus[i]*A_temp;
            }
            plus=thevecp;
            minus=thevecm;
}
</code></pre>
<p>Im Gegensatz zu</p>
<pre><code>void multiply(MontgRep &amp;a, const int &amp;B_temp) {
//Folgender Code geht auch ist aber langsamer!!!!!

             for (int i=plus.length()-1; i&gt;=0;  i--) {
                plus[i] = a.plus[i] * B_temp;
                minus[i] = a.minus[i] * B_temp;
            }
        }
</code></pre>
<p><strong>Eigentlich</strong> dachte ich, dass es fuer solch grundlegende Sachen zu viel Aufwand ist, noch zusaetzlich lokale Objekte zu erstellen ( auch wenn sie nicht so gross sind ), wenn man schon Speicher fuer das referenzierte Objekt zur Verfuegung hat, welchen man doch auch nutzen kann ( mir wurde sogar mal geraten, dass man den auch nutzen sollte ).<br />
<strong>Aber</strong> es hat sich herausgestellt, dass das Arbeiten mit einer erstellten einer Kopie und abschliessendem Zuweisen der Werte auf das referenzierte Objekt schneller geht!?</p>
<p>Dieses wurde dann versucht auf andere Funktionen anzuwenden, jedoch mit unterschiedlichem Erfolg, sprich es wurde an anderer Stelle mit <strong>voellig aequivalenter Herangehensweise</strong> langsamer.</p>
<p>Das richt in meiner Nase nach einer speziellen Benutzung von Referenzen. Da diese mir einfach noch nicht bekannt ist, hoffe auf diesem Wege einen Rat zu bekommen.</p>
<p>Hinweise auf Buecher, die das gut umschreiben, werden natuerlich auch dankend angemommen, falls jemand damit dienen kann ... !</p>
<p>Ueber Reaktionen waere ich natuerlich sehr dankbar!</p>
<p>MfG<br />
#50</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1113200</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1113200</guid><dc:creator><![CDATA[Raute50]]></dc:creator><pubDate>Tue, 08 Aug 2006 16:46:34 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz vs. lokale Kopie on Tue, 08 Aug 2006 16:56:18 GMT]]></title><description><![CDATA[<p>Raute50 schrieb:</p>
<blockquote>
<p>Dieses wurde dann versucht auf andere Funktionen anzuwenden, jedoch mit unterschiedlichem Erfolg, sprich es wurde an anderer Stelle mit <strong>voellig aequivalenter Herangehensweise</strong> langsamer.</p>
</blockquote>
<p>jo, ist klar, ne.</p>
<p>referenz macht ne indirektion mehr bei jedem zugriff. wenn du dann damit eine hypergeometrische matrizeninversion machst, bei der für hundert matrixelemente 100^4 zugriffe (indirektionen) passieren, aber sonst nix wesentliches, wäre ne lokale kopie besser. nur einmal kopieren und dann 100000000 indirektionen sparen.</p>
<p>machste aber nur ne observation, ob es ne einheitsmatix ist, guckste mal eben durch die indirektion die matrix an und returnst dein ergebnis, statt erst 100 elemente zu kopieren und dann nur 10 anzugucken.</p>
<p>als faustregel sollte gelten, daß referenz schneller ist als kopie.</p>
<p>eine alternative ist sicherlich auch, sich ne referenz zu ziehen und nen zeiger auf die interne repräsentation lokal anzulegen und auf dem den teuren algo auszuführen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1113211</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1113211</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 08 Aug 2006 16:56:18 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz vs. lokale Kopie on Tue, 08 Aug 2006 17:17:09 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Raute50 schrieb:</p>
<blockquote>
<p>Dieses wurde dann versucht auf andere Funktionen anzuwenden, jedoch mit unterschiedlichem Erfolg, sprich es wurde an anderer Stelle mit <strong>voellig aequivalenter Herangehensweise</strong> langsamer.</p>
</blockquote>
<p>jo, ist klar, ne.</p>
</blockquote>
<p>Was soll mir klar sein ? Das es mal klappt und mal nicht ?!</p>
<p>volkard schrieb:</p>
<blockquote>
<p>referenz macht ne indirektion mehr bei jedem zugriff. wenn du dann damit eine hypergeometrische matrizeninversion machst, bei der für hundert matrixelemente 100^4 zugriffe (indirektionen) passieren, aber sonst nix wesentliches, wäre ne lokale kopie besser. nur einmal kopieren und dann 100000000 indirektionen sparen.</p>
<p>machste aber nur ne observation, ob es ne einheitsmatix ist, guckste mal eben durch die indirektion die matrix an und returnst dein ergebnis, statt erst 100 elemente zu kopieren und dann nur 10 anzugucken.</p>
<p>als faustregel sollte gelten, daß referenz schneller ist als kopie.</p>
<p>eine alternative ist sicherlich auch, sich ne referenz zu ziehen und nen zeiger auf die interne repräsentation lokal anzulegen und auf dem den teuren algo auszuführen.</p>
</blockquote>
<p>Wir benutzen die referenzierten Objekte schon ... Die Sache ist nur die, dass wir manchmal ein lokales Objekt erstellen dem die Ergebnisse ( in dem obigen Beispiel ein einfaches Produkt ) zugewiesen werden und das schneller ist, als einfach dem referenzierten Objekt gleich die Werte zuzuweisen ...<br />
Aber das ist von Fall zu Fall unterschiedlich und fuer uns nicht ersichtlich woran das liegen mag ... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>MfG<br />
#50</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1113223</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1113223</guid><dc:creator><![CDATA[Raute50]]></dc:creator><pubDate>Tue, 08 Aug 2006 17:17:09 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz vs. lokale Kopie on Tue, 08 Aug 2006 17:48:23 GMT]]></title><description><![CDATA[<p>Es gibt verschiedene Möglichkeiten. Abhängig vom Zielsystem könnte der registersatz zu klein sein, um alle temporären Ergebnisse aufzunehmen (dann entsteht das von volkard angesprochene problem mit der permanenten indirektion - nebenbei ist es kein vorteil, A bzw. B_temp als referenz zu übergeben). die variante ohne lokale vektoren leidet außerdem möglicherweise unter einem aliasing-problem. des weiteren ist anzumerken, dass die schleife mit dekrementierendem index arbeitet - das ist i.allg. keine gute idee, wenn hardware-prefetching im spiel ist. es könnte aus demselben grund auch sinnvoll sein, den plus- und minus-teil in getrennten schleifen zu verarbeiten. probier mal folgende varianten (annahme ist, dass vec_ZZ_p die daten in einem array speichert):<br />
(restrict als #define auf __restrict__ o.ä. falls dein compiler das unterstützt, sonst leer)</p>
<pre><code class="language-cpp">void multiply(MontgRep &amp;a, int A_temp) {
            vec_ZZ_p thevecp,thevecm;
            thevecp.SetLength(plus.length());
            thevecm.SetLength(plus.length());

            ptrdiff_t i = -plus.length();
            int* restrict s = &amp;a.plus[0] - i;
            int* restrict t = &amp;thevecp[0] - i;
            do t[i]=s[i]*a while (++i);
            i = -plus.length();
            s = &amp;a.minus[0] - i;
            t = &amp;thevecm[0] - i;
            do t[i]=s[i]*a while (++i);
            plus=thevecp;
            minus=thevecm;
}
</code></pre>
<p>vs.</p>
<pre><code class="language-cpp">void multiply(MontgRep &amp;a, int B_temp) {

            ptrdiff_t i = -plus.length();
            int* s = &amp;a.plus[0] - i;
            int* t = &amp;plus[0] - i;
            do t[i]=s[i]*a while (++i);
            i = -plus.length();
            s = &amp;a.minus[0] - i;
            t = minus[0] - i;
            do t[i]=s[i]*a while (++i);
        }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1113249</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1113249</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 08 Aug 2006 17:48:23 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz vs. lokale Kopie on Wed, 16 Aug 2006 20:09:32 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Es gibt verschiedene Möglichkeiten. Abhängig vom Zielsystem könnte der registersatz zu klein sein, um alle temporären Ergebnisse aufzunehmen (dann entsteht das von volkard angesprochene problem mit der permanenten indirektion - **(1)**nebenbei ist es kein vorteil, A bzw. B_temp als referenz zu übergeben). die variante ohne lokale vektoren leidet außerdem möglicherweise unter einem **(2)**aliasing-problem. <strong>(3)des weiteren ist anzumerken, dass die schleife mit dekrementierendem index arbeitet - das ist i.allg. keine gute idee, wenn hardware-prefetching im spiel ist.</strong> (4)es könnte aus demselben grund auch sinnvoll sein, den plus- und minus-teil in getrennten schleifen zu verarbeiten. probier mal folgende varianten (annahme ist, dass vec_ZZ_p die daten in einem array speichert)</p>
</blockquote>
<p>zu (1) :<br />
also was wir bis dato gefunden haben ist der Bezug zwischen Objektgröße und Sinn des Referenzierens ...<br />
Also es ist fast gratis eine Kopie von int abzuschreiben, dagegen macht es bei sehr großen Objekten mehr Sinn eine konstante Referenz zu übergeben ...<br />
Das ist das was wir gefunden haben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
<p>zu (2) :<br />
Variante ohne Lokale Vektoren führen zu waaaaaas ?? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>zu (3) :<br />
Warum das noch mal ?<br />
Ich sehe ein, dass wenn man bei einem Vektor in der Regel um einen konstanten Faktor im Speicher geht, dass man das irgendwie cleverer machen kann ...<br />
Aber bei vielen Aufrufen der Multiply und bei jedem Durchlauf häufigen Aufrufen von .length() dachten wir, da es syntaktisch eh egal ist, in welcher Reihenfolge da multipliziert wird, dass nur 1x ein Aufruf von .length() wesentlich günstiger wäre ... ????<br />
Was hat das nun noch mal mit hardware prefetching zu tun ????</p>
<p>zu (4) :<br />
Haben wir ausprobiert ... ergab keinen Vorteil...</p>
<p>Dann mal DANKE!</p>
<p>Haben unser Problem relativ gut gelöst ... besteht also nicht mehr ...</p>
<p>#50</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1118721</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1118721</guid><dc:creator><![CDATA[Raute50]]></dc:creator><pubDate>Wed, 16 Aug 2006 20:09:32 GMT</pubDate></item></channel></rss>