<?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[Arrays in Templates: was macht der Compiler daraus?]]></title><description><![CDATA[<p>Im folgenden (fiktiven) Template werden mittels <code>index</code> viele Arrays adressiert. Die Function <code>function</code> bestimmt zur Laufzeit, welches fertige Template aufgerufen wird. Der Compiler generiert die beiden Funktionstemplates. Ich hoffe das richtig verstanden zu haben:</p>
<pre><code class="language-cpp">int function(data_c &amp; data, const int index) {
  if (index == 0) {
    return template_function&lt;0&gt;(data);
  else
    return template_function&lt;1&gt;(data);
}

template&lt;int index&gt;
int template_function(data_c &amp; data) {
  // a lot of code like this:
  data[index].member21--;
  data[index].member36+=4;
  data[index].member18&amp;=CONST_MASK_A;
  data[index].member09^=RANDOM_KEY;
  // ...
  return data[index].member45;
}
</code></pre>
<p>Aber was passiert jetzt mit <code>data[index]</code> , wird das intern vom Compiler in eine Variable aufgelöst oder bleibt es weiterhin ein Array. Es geht mir darum, eine hohe Laufzeiteffizient zu bekommen. Auf <code>data[index]</code> (data[0] oder data[1]) wird andauernd zugegriffen.</p>
<p>Bisher habe ich beide Funktionen für <code>index=0</code> und <code>index=1</code> manuell codiert und auf das 2-dimensionale Array komplett verzichtet (Klingt etwas stupide, musste aber sein, da es um Geschwindigkeit geht).</p>
<p>Genauso frage ich mich, ob</p>
<pre><code class="language-cpp">const int WHITE=0;
const int BLACK=0;
data[WHITE].member23
data[BLACK].member23
</code></pre>
<p>genauso effizient (schnell) arbeitet wie</p>
<pre><code class="language-cpp">data_white.member23
data_black.member23
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/253060/arrays-in-templates-was-macht-der-compiler-daraus</link><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 02:10:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/253060.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 28 Oct 2009 09:55:32 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 09:55:32 GMT]]></title><description><![CDATA[<p>Im folgenden (fiktiven) Template werden mittels <code>index</code> viele Arrays adressiert. Die Function <code>function</code> bestimmt zur Laufzeit, welches fertige Template aufgerufen wird. Der Compiler generiert die beiden Funktionstemplates. Ich hoffe das richtig verstanden zu haben:</p>
<pre><code class="language-cpp">int function(data_c &amp; data, const int index) {
  if (index == 0) {
    return template_function&lt;0&gt;(data);
  else
    return template_function&lt;1&gt;(data);
}

template&lt;int index&gt;
int template_function(data_c &amp; data) {
  // a lot of code like this:
  data[index].member21--;
  data[index].member36+=4;
  data[index].member18&amp;=CONST_MASK_A;
  data[index].member09^=RANDOM_KEY;
  // ...
  return data[index].member45;
}
</code></pre>
<p>Aber was passiert jetzt mit <code>data[index]</code> , wird das intern vom Compiler in eine Variable aufgelöst oder bleibt es weiterhin ein Array. Es geht mir darum, eine hohe Laufzeiteffizient zu bekommen. Auf <code>data[index]</code> (data[0] oder data[1]) wird andauernd zugegriffen.</p>
<p>Bisher habe ich beide Funktionen für <code>index=0</code> und <code>index=1</code> manuell codiert und auf das 2-dimensionale Array komplett verzichtet (Klingt etwas stupide, musste aber sein, da es um Geschwindigkeit geht).</p>
<p>Genauso frage ich mich, ob</p>
<pre><code class="language-cpp">const int WHITE=0;
const int BLACK=0;
data[WHITE].member23
data[BLACK].member23
</code></pre>
<p>genauso effizient (schnell) arbeitet wie</p>
<pre><code class="language-cpp">data_white.member23
data_black.member23
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1799508</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799508</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 09:55:32 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 10:12:10 GMT]]></title><description><![CDATA[<p>es kommt drauf an was für ein Typ data_c ist. Der Compiler sieht, dass der Indeoperator (operator[]) auf ein data_c angewendet wird und macht, was immer in dem Fall richtig ist. Wenn data_c ein Pointer-Typ ist wird die entsprechende Pointer-Arithmetik angewandt, wenns ein typedef für einen vetor oder eine map ist wird deren op[] aufgerufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799519</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799519</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 28 Oct 2009 10:12:10 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 10:31:38 GMT]]></title><description><![CDATA[<p>Don´t optimize prematurely!</p>
<p>Oft macht es keinen Sinn, sich besonders trickreiche Konstrukte zu überlegen mit dem Ziel, den Code schneller zu machen. Wenn der Algorithmus der Richtige ist optimiert der Compiler besser als jeder Programmierer. Wenn deine Lösung trickreich ist wird der Code komplizierter und du erschwerst dem Compiler die Optimierungsarbeit.<br />
Am besten benutzt du einen Profiler und untersuchst das Laufzeitverhalten deiner Anwendung. Der Profiler zeigt dir die Engstellen auf und da könntest du dann versuchen von Hand zu optimieren. Meiner Erfahrung nach bringt das aber selten etwas, und wenn doch, dann nicht viel. Die Auswahl des passenden Algorithmus ist eine viel wichtigere Entscheidung, und da wir nicht wissen, was du erreichen willst kann man wenig zu deinem Code sagen.<br />
Die template Lösung mit festen Indizes halte ich für nicht optimal, kannst du nicht einfach das Arrayelement per Referenz übergeben? Oder direkt auf das Element zugreifen? Da wiederholt auf das Arrayelement zugegriffen wird wird der Compiler den Zugriff optimieren, sodass weitere Zugriffe so effizient wie möglich sind.<br />
Du kannst ja mal einen Vergleich zwischen deinem Code und diesen beiden Schnipseln fahren:</p>
<pre><code class="language-cpp">int function_1( data_c&amp; data, int index )
{
  data[index].member21--;
  data[index].member36+=4;
  data[index].member18&amp;=CONST_MASK_A;
  data[index].member09^=RANDOM_KEY;
  // ...
  return data[index].member45;
}

int function_2( data_c&amp; data, int index )
{
  array_element_type&amp; object = data[index];

  object.member21--;
  object.member36+=4;
  object.member18&amp;=CONST_MASK_A;
  object.member09^=RANDOM_KEY;
  // ...
  return object.member45;
}
</code></pre>
<p>Ich glaube nicht, dass da messbare Unterschiede festzustellen sind.</p>
<p>PS:<br />
Integrale Datentypen per const zu übergeben macht keinen Sinn, es sind temporaries, die nur in der Funktion sichtbar sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799526</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Wed, 28 Oct 2009 10:31:38 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 10:46:04 GMT]]></title><description><![CDATA[<p>Hallo <em>DocShoe</em></p>
<p>Es geht um meine Schachengine, in der fast alle Algorithmen doppelt vorhanden sind. Also für Weiss und für Schwarz. Das Problem ist der redundante Code. Die Algorithmen unterscheiden sich ja nur geringfügig. Es müssen im Grunde nur die Reihen umgekehrt werden und der Gegner gespiegelt werden:</p>
<p><strong>So ist es aktuell (Ausschnitt):</strong></p>
<pre><code class="language-cpp">// white rook
case PIECE_ROOK:
    board.key_pieces^=random_white_rook[from];
    board.key_pieces^=random_white_rook[to];
    board.white_rook_bitboard&amp;=bitboard_clear[from];
    board.white_rook_bitboard|=bitboard_set[to];
    board.piece[to]=PIECE_WHITE_ROOK;
    board.moves[from]++;
    break;

// black rook
case PIECE_ROOK:
    board.key_pieces^=random_black_rook[from];
    board.key_pieces^=random_black_rook[to];
    board.black_rook_bitboard&amp;=bitboard_clear[from];
    board.black_rook_bitboard|=bitboard_set[to];
    board.piece[to]=PIECE_BLACK_ROOK;
    board.moves[from]++;
    break;
</code></pre>
<p><strong>So könnte es aussehen (Ausschnitt):</strong></p>
<pre><code class="language-cpp">// white rook / black rook
case PIECE_ROOK:
    board.key_pieces^=random_rook[color][from];
    board.key_pieces^=random_rook[color][to];
    board.rook_bitboard[color]&amp;=bitboard_clear[from];
    board.rook_bitboard[color]|=bitboard_set[to];
    board.piece[to]=piece_rook[color];
    board.moves[from]++;
    break;
</code></pre>
<p>Es sind etwa 80 Algorithmen die etwa 50% der gesamten Rechenzeit konsumieren. Wenn eine neue Konstruktion zwar weniger Codierungsaifwand bedeutet aber merklich langsamer ist (&gt; 10%) habe ich nichts davon.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799541</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799541</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 10:46:04 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 10:52:16 GMT]]></title><description><![CDATA[<p>Nochmal ganz kurz:</p>
<p>**<br />
A: Mein Ziel ist es die Codemenge zu reduzieren, damit ich Änderungen und Verbesserungen nicht immer doppelt codieren muss.</p>
<p>B: Die Laufzeiteffizient soll aber nicht zu sehr darunter leiden<br />
**</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799550</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799550</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 10:52:16 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 11:09:08 GMT]]></title><description><![CDATA[<p>Da hilft nur eins: Untersuch das Laufzeitverhalten mit einem Profiler. Oder bau dir einen minmalen Anwendungsfall, der das Problem beeinhaltet und schau dir an, wieviel Zeit ein (10, 1.000, 1.000.000, 100.000.000) Durchlauf benötigt (unter Windows mit QueryPerformanceCounter/QueryPerformanceFrequency). Damit sollest du abschätzen können, ob es immer noch schnell genug ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799563</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799563</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Wed, 28 Oct 2009 11:09:08 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 11:13:03 GMT]]></title><description><![CDATA[<p>Auch wenn ich mich meinen Vorrednern bezüglich frühzeitiger Optimierung anschließen möchte: Wenn du zwei fast gleiche Algorithmen hast, dann versuch das doch mit Templates zusammenzufassen. Templates werden zur Compilezeit ausgewertet. Entsprechend können auch Arrayzugriffe mit einem Templateparameter als Index zur Compilezeit ausgewertet werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799564</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799564</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 28 Oct 2009 11:13:03 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 11:19:38 GMT]]></title><description><![CDATA[<p>Eben das war genau meine Frage bzw mein Vorschlag!</p>
<pre><code class="language-cpp">void make_move(int color, int turn, int move) {
  if (turn == WHITE)
    make_move_template&lt;WHITE&gt;(turn, move);
  else
    make_move_template&lt;BLACK&gt;(turn, move);
}

template&lt;int color&gt;
void make_move_template(int turn, int move) {
  switch (piece(move)) {
  // ...
  case PIECE_ROOK: 
    board.key_pieces^=random_rook[color][from]; 
    board.key_pieces^=random_rook[color][to]; 
    board.rook_bitboard[color]&amp;=bitboard_clear[from]; 
    board.rook_bitboard[color]|=bitboard_set[to]; 
    board.piece[to]=piece_rook[color]; 
    board.moves[from]++; 
    break;
  // ...
}
</code></pre>
<p><strong>?</strong></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799566</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799566</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 11:19:38 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 11:29:36 GMT]]></title><description><![CDATA[<p>Jetzt sind wir da, wo wir am Anfang waren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Mach dir doch einfach zwei Funktionen:</p>
<pre><code class="language-cpp">template&lt;int Color&gt;
void make_move( int turn, int move )
{
  ...
}

void make_move( int color, int turn, int move )
{
  ...
}
</code></pre>
<p>Und miss jetzt endlich das Laufzeitverhalten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799569</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799569</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Wed, 28 Oct 2009 11:29:36 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 11:33:17 GMT]]></title><description><![CDATA[<p>mache ich ja schon, bis später... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799573</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799573</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 11:33:17 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 13:35:11 GMT]]></title><description><![CDATA[<p>Nur so aus Interesse wuerde mich mal interessieren, warum du fuer schwarz anderen Code brauchst? Normalerweise kann ich doch ein zu einer gewissen Stellung, in der weiss am Zug ist, eine analoge Situation mit schwarz am Zug konstruieren, wo schwarz die gleichen Zugmoeglichkeiten bzw. Siegchancen hat. Die Zuege vor dieser Stellung interessieren fuer kaum eine Regel und sind dann auch symmetrisch - es ist also fast egal wie man zu der Stellung kommt. Also muesste dem Algorithmus die Seite eigentlich voellig egal sein. f'`8k</p>
<p><div class="plugin-markdown"><input type="checkbox" id="checkbox218909" /><label for="checkbox218909"></label></div><a href="http://tggc.tg.funpic.de/index.php?cat=8&amp;page=5" rel="nofollow">Autocogito</a></p>
<p>Gruß, TGGC (<a href="http://www.gamestar.de/index.cfm?pid=819&amp;pk=12279" rel="nofollow">Was Gamestar sagt...</a>)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799650</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799650</guid><dc:creator><![CDATA[TGGC]]></dc:creator><pubDate>Wed, 28 Oct 2009 13:35:11 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 13:43:34 GMT]]></title><description><![CDATA[<p>Ja es ist auch (fast) vollkommen egal. Lediglich die Reihen (bei Bauern - Doppelschritt oder Umwandlung) sowie die Rochadefelder sind unterschiedlich. Und bei den Bewertungen eben die Vorzeichen der Boni und Mali.</p>
<p>Mein Konzept war bisher möglichst speziellen Code schreiben, da dieser einfacher ist (und schneller??). Aber dadurch wird der Code redundanter.</p>
<p>Ergebnisse folgen in Kürze...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799658</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799658</guid><dc:creator><![CDATA[Tomahawk]]></dc:creator><pubDate>Wed, 28 Oct 2009 13:43:34 GMT</pubDate></item><item><title><![CDATA[Reply to Arrays in Templates: was macht der Compiler daraus? on Wed, 28 Oct 2009 14:00:14 GMT]]></title><description><![CDATA[<p>Tomahawk schrieb:</p>
<blockquote>
<p>Lediglich die Reihen (bei Bauern - Doppelschritt oder Umwandlung) sowie die Rochadefelder sind unterschiedlich. Und bei den Bewertungen eben die Vorzeichen der Boni und Mali.</p>
</blockquote>
<p>Ja, aber auch das ist voellig symmetrisch. Ich wuerde einfach eine KI fuer weiss schreiben, und wenn ich einen schwarzen Zug berechne, dann konstruiere ich die analoge weisse Position, loese diese und transformiere den Zug zurueck. f'`8k</p>
<p>Gruß, TGGC (<a href="http://www.gamestar.de/index.cfm?pid=819&amp;pk=12279" rel="nofollow">Was Gamestar sagt...</a>)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1799682</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1799682</guid><dc:creator><![CDATA[TGGC]]></dc:creator><pubDate>Wed, 28 Oct 2009 14:00:14 GMT</pubDate></item></channel></rss>