<?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[Schnelles Iterieren über Matrix mit beliebiger Dimensionalität]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte gerne über eine Matrix mit beliebiger Dimensionalität iterieren, d.h. eine Schleifenvariante, die mit folgendem Umgehen kann:</p>
<pre><code class="language-cpp">std::vector&lt;int&gt; vec1(10 * 20 * 30);
std::vector&lt;int&gt; vec2(10 * 20 * 30 * 40);
</code></pre>
<p>, wobei hier jeder Faktor des Produkts der Ausdehnung einer Dimension entspricht. Wichtig: Ich brauche in jeder Iteration die Indizes, also bei einer zweidimensionalen Matrix mit <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>a</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">a_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord"><span class="mord mathit">a</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord scriptstyle cramped"><span class="mord mathit">i</span><span class="mord mathit" style="margin-right:0.05724em;">j</span></span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span></span></span> eben i und j.</p>
<p>Eine einfache Lösung fand ich, die aber langsam ist. MSVC12 gibt für</p>
<pre><code class="language-cpp">#include &lt;ctime&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;

using namespace std;

struct type
{
	unsigned int cost;
};

int main()
{
	using namespace std;

	vector&lt;type&gt; vec(11 * 50 * 50 * 50 * 50);

	clock_t start = clock();

	for(unsigned int a = 0; a &lt; 50; ++a)
    {
		for(unsigned int b = 0; b &lt; 50; ++b)
		{
			for(unsigned int c = 0; c &lt; 50; ++c)
            {
            	for(unsigned int d = 0; d &lt; 50; ++d)
                {
                	for(unsigned int e = 0; e &lt; 11; ++e)
                    {
    					vec[a + b * 50 + c * 50 + d * 50 + e * 50].cost = a + b + c + d + e;
                    }
                }
            }
		}

	}

	clock_t end = clock();

	unsigned int indices[] = {0, 0, 0, 0, 0};
	unsigned int maxIndices[] = {50, 50, 50, 50, 11};

	clock_t start2 = clock();

	for(;;)
	{
		vec[indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50].cost =
			indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50;

		int n;
		for(n = 4; n &gt;= 0; --n)
		{
			if(++indices[n] == maxIndices[n])
				indices[n] = 0;
            else
				break;
		}

		if(n &lt; 0) break;
	}

	clock_t end2 = clock();

	std::cout &lt;&lt; &quot;Diff1: &quot; &lt;&lt; end - start &lt;&lt; '\n'
		&lt;&lt; &quot;Diff2: &quot; &lt;&lt; end2 - start2 &lt;&lt; '\n';

	char dummy;
	std::cin &gt;&gt; dummy;

	return 0;
}
</code></pre>
<p>aus:</p>
<blockquote>
<p>Diff1: 57<br />
Diff2: 421</p>
</blockquote>
<p>Messe ich falsch? Das Ergebnis scheint verheerend. Es ist nicht <em>der</em> Flaschenhals in meiner eigentlichen Simulation, aber es ist bemerkbar. Gibt es eine bessere Lösung?</p>
<p>Danke und beste Grüße <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/topic/322205/schnelles-iterieren-über-matrix-mit-beliebiger-dimensionalität</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Jul 2026 19:41:03 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/322205.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 11 Dec 2013 10:21:03 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 10:21:03 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte gerne über eine Matrix mit beliebiger Dimensionalität iterieren, d.h. eine Schleifenvariante, die mit folgendem Umgehen kann:</p>
<pre><code class="language-cpp">std::vector&lt;int&gt; vec1(10 * 20 * 30);
std::vector&lt;int&gt; vec2(10 * 20 * 30 * 40);
</code></pre>
<p>, wobei hier jeder Faktor des Produkts der Ausdehnung einer Dimension entspricht. Wichtig: Ich brauche in jeder Iteration die Indizes, also bei einer zweidimensionalen Matrix mit <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>a</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">a_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord"><span class="mord mathit">a</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord scriptstyle cramped"><span class="mord mathit">i</span><span class="mord mathit" style="margin-right:0.05724em;">j</span></span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span></span></span> eben i und j.</p>
<p>Eine einfache Lösung fand ich, die aber langsam ist. MSVC12 gibt für</p>
<pre><code class="language-cpp">#include &lt;ctime&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;

using namespace std;

struct type
{
	unsigned int cost;
};

int main()
{
	using namespace std;

	vector&lt;type&gt; vec(11 * 50 * 50 * 50 * 50);

	clock_t start = clock();

	for(unsigned int a = 0; a &lt; 50; ++a)
    {
		for(unsigned int b = 0; b &lt; 50; ++b)
		{
			for(unsigned int c = 0; c &lt; 50; ++c)
            {
            	for(unsigned int d = 0; d &lt; 50; ++d)
                {
                	for(unsigned int e = 0; e &lt; 11; ++e)
                    {
    					vec[a + b * 50 + c * 50 + d * 50 + e * 50].cost = a + b + c + d + e;
                    }
                }
            }
		}

	}

	clock_t end = clock();

	unsigned int indices[] = {0, 0, 0, 0, 0};
	unsigned int maxIndices[] = {50, 50, 50, 50, 11};

	clock_t start2 = clock();

	for(;;)
	{
		vec[indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50].cost =
			indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50;

		int n;
		for(n = 4; n &gt;= 0; --n)
		{
			if(++indices[n] == maxIndices[n])
				indices[n] = 0;
            else
				break;
		}

		if(n &lt; 0) break;
	}

	clock_t end2 = clock();

	std::cout &lt;&lt; &quot;Diff1: &quot; &lt;&lt; end - start &lt;&lt; '\n'
		&lt;&lt; &quot;Diff2: &quot; &lt;&lt; end2 - start2 &lt;&lt; '\n';

	char dummy;
	std::cin &gt;&gt; dummy;

	return 0;
}
</code></pre>
<p>aus:</p>
<blockquote>
<p>Diff1: 57<br />
Diff2: 421</p>
</blockquote>
<p>Messe ich falsch? Das Ergebnis scheint verheerend. Es ist nicht <em>der</em> Flaschenhals in meiner eigentlichen Simulation, aber es ist bemerkbar. Gibt es eine bessere Lösung?</p>
<p>Danke und beste Grüße <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/2371098</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371098</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Wed, 11 Dec 2013 10:21:03 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 10:34:05 GMT]]></title><description><![CDATA[<p>Die Frage ist, was der eigentliche Flaschenhals ist.</p>
<p>Wenn du über (große) Matrizen iterierst , kannst du mit etwas Geschicklich viel Geschwindigkeit rausholen (Stichwort Speicherzugriffszeite, Linesize, Cachegröße, Blocking, Unrolling, usw...)</p>
<p>Dein Frage richtet sich jedoch in Richtung Dimensionalität. Ich würd mir mehrere Klassen schreiben, die jede für eine gewisse Dimensionalität zuständig ist. Diese würde ich dann jeweils etwas optimieren (ja, ist etwas Coderedundanz).</p>
<p>Was du in deinem Code andeutest, das jongliert etwas mit den Indizes rum. Ich hab jetzt leider grad nicht die Zeit mich da reinzudenken, es sieht auf den ersten Blick jedoch etwas komisch aus. Kommen die gleichen Ergebnisse raus? Ja müssten, denke ich.</p>
<p>Aber der Grund, dass es langsamer ist, dass du ungünstig auf den Speicher zugreifst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2371102</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371102</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Wed, 11 Dec 2013 10:34:05 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 10:45:04 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">vec[a + b * 50 + c * 50 + d * 50 + e * 50]
</code></pre>
<p>Auf welchen Index greifst du hier zu? Tip: es ist nicht (a, b, c, d, e), d.h. du iterierst nicht ueber die Matrix.</p>
<p>Desweiteren ist dein Iterationsschema in Variante 1 nicht cachefriendly. Variante 2 habe ich nicht angeschaut, da da ganze sowieso fehlerhaft ist.</p>
<p>Vergleiche bitte auch:</p>
<pre><code class="language-cpp">vec[a + b * 50 + c * 50 + d * 50 + e * 50].cost = a + b + c + d + e;
</code></pre>
<p>mit</p>
<pre><code class="language-cpp">vec[indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50].cost = 
indices[0] + indices[1] * 50 + indices[2] * 50 + indices[3] * 50 + indices[4] * 50;
</code></pre>
<p>Es ist nicht das gleiche. Dein Benchmark ist hinfaellig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2371103</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371103</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 11 Dec 2013 10:45:04 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 10:47:05 GMT]]></title><description><![CDATA[<p>Skym0sh0:</p>
<blockquote>
<p>Aber der Grund, dass es langsamer ist, dass du ungünstig auf den Speicher zugreifst.</p>
</blockquote>
<p>Wie verbessere ich das?</p>
<p>Die Coderedundanz-Variante wollte ich eigentlich vermeiden, wenn möglich. Das wird ja echt viel Schreibarbeit.</p>
<p>knivil:<br />
Stimmt, das ist so unsinnig. Spielt das performancetechnisch eine Rolle? Edit: Nach Korrektur sind die Varianten tatsächlich gleich schnell, so was.</p>
<p>Wie könnte ich Variante1 cachefreundlicher machen? Aber eigentlich will ich ja eher Variante2 optimieren.</p>
<p>Edit: Den Rest lese ich gleich, schon Mal danke für die Anregungen. <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/2371104</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371104</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Wed, 11 Dec 2013 10:47:05 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 10:47:54 GMT]]></title><description><![CDATA[<blockquote>
<p>Stimmt, das ist so unsinnig. Spielt das performancetechnisch eine Rolle?</p>
</blockquote>
<p>Definitiv. Wenn ich nur ca. 40 kByte anfasse, dann passt das vermutlich alles in den Cache. Weiterhin moechtest du einen Benchmark um ueber Matrizen zu iterieren. Was hilft dir da ein Test, der das nicht testet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2371105</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371105</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 11 Dec 2013 10:47:54 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelles Iterieren über Matrix mit beliebiger Dimensionalität on Wed, 11 Dec 2013 11:53:22 GMT]]></title><description><![CDATA[<p>iterieren tust du am besten von 0 bis N.</p>
<p>Wenn du bei dem index I bist, musst du anhand von I herausbekommen welche &quot;indexes&quot; du verwenden willst - dein a,b,c,... Nur ist das halt willkürlich festgelegt.</p>
<p>du könntest zB bei einer 2 dim matrix sagen:<br />
Bei I hast du a = I/spalten und b = I%spalten</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2371119</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2371119</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 11 Dec 2013 11:53:22 GMT</pubDate></item></channel></rss>