<?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[Kann man das noch optimieren? (Mandelbrot-Berechnung)]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich arbeite zurzeit an einem Madelbrot/Apfelmännchen-Programm.<br />
Das Bottleneck des Programms ist folgendes:</p>
<pre><code class="language-cpp">int calculateNumIterations(mandelType x, mandelType y)
{
	mandelType x1=0, x2=0, y1=0;
	for(int i = 0; i &lt; numIterations; ++i)
	{
		x2 = x1*x1 - y1*y1 + x ;
		y1 = 2*x1*y1 + y;
		x1 = x2;
		if(x1*x1 + y1*y1  &gt; 4)
		{
			return i;
		}
	}
	return numIterations;
}
</code></pre>
<p>Ich denke eig nicht, dass man da noch viel machen kann, aber falls doch wäre es schön, weil das Programm alles an geschwindigkeit brauchen kann, was möglich ist.<br />
mandelType ist übrigens nen typedef für double im moment.<br />
Würde inline asm was bringen? Vermutlich eher nicht, da der compiler das ja selbst schon gut hinkriegen sollte, oder?</p>
<p>Demnächst stell ich vermutlich auf berechnung im fragment-shader mit fixed-point-arithmetik um (mit single precision hab ich das schon hinbekommen, der Geschwindigkeitsvorteil ist RIESIG aber single precision kann man vergessen...). Aber bis es soweit ist arbeite hier hierdran noch ein wenig.</p>
<p>P.S.: Wenn wer das Programm haben will, einfach Bescheid sagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/293527/kann-man-das-noch-optimieren-mandelbrot-berechnung</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 11:29:01 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/293527.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 05 Oct 2011 08:27:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:27:39 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich arbeite zurzeit an einem Madelbrot/Apfelmännchen-Programm.<br />
Das Bottleneck des Programms ist folgendes:</p>
<pre><code class="language-cpp">int calculateNumIterations(mandelType x, mandelType y)
{
	mandelType x1=0, x2=0, y1=0;
	for(int i = 0; i &lt; numIterations; ++i)
	{
		x2 = x1*x1 - y1*y1 + x ;
		y1 = 2*x1*y1 + y;
		x1 = x2;
		if(x1*x1 + y1*y1  &gt; 4)
		{
			return i;
		}
	}
	return numIterations;
}
</code></pre>
<p>Ich denke eig nicht, dass man da noch viel machen kann, aber falls doch wäre es schön, weil das Programm alles an geschwindigkeit brauchen kann, was möglich ist.<br />
mandelType ist übrigens nen typedef für double im moment.<br />
Würde inline asm was bringen? Vermutlich eher nicht, da der compiler das ja selbst schon gut hinkriegen sollte, oder?</p>
<p>Demnächst stell ich vermutlich auf berechnung im fragment-shader mit fixed-point-arithmetik um (mit single precision hab ich das schon hinbekommen, der Geschwindigkeitsvorteil ist RIESIG aber single precision kann man vergessen...). Aber bis es soweit ist arbeite hier hierdran noch ein wenig.</p>
<p>P.S.: Wenn wer das Programm haben will, einfach Bescheid sagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127437</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127437</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:27:39 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:44:17 GMT]]></title><description><![CDATA[<p>Ich kenne Mandelbrot nur vom Hören.<br />
Wenn wirklich diese simple Funktion die Bremse ist, dann kann man da nicht wirklich viel machen.</p>
<p>Profile mal dein Programm und optimiere dann. Mach dir nicht so viele Gedanken während dem programmieren ob das langsam sein könnte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127442</guid><dc:creator><![CDATA[asdfasdf]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:44:17 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:46:49 GMT]]></title><description><![CDATA[<p>Ich fürchte, da lässt sich nichts mehr optimieren, was der Compiler nicht sowieso optimieren würde. Ich nehme an, numIterations ist eine Compilezeitkonstante, die der Compiler kennt? Was nicht so toll ist, ist natürlich ein if in jedem Durchgang. Parallelisierbar ist die Schleife auch nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> . Was Parallelisierbar sein sollte, ist jedoch der Aufruf der Funktion. Das sollte sehr gut skalieren.</p>
<p>Was man noch machen könnte ist, mal darüber nachzudenken, das Problem ganz anders zu formulieren, vielleicht gibt's eine bessere Variante. Ich kenne Mandelbrot selber nicht aus der Praxis, aber da werden andere doch schon viel drüber geschrieben haben:<br />
<a href="http://en.wikipedia.org/wiki/Mandelbrot_set#Computer_drawings" rel="nofollow">http://en.wikipedia.org/wiki/Mandelbrot_set#Computer_drawings</a><br />
<a href="http://en.wikipedia.org/wiki/Mandelbrot_set#Optimizations" rel="nofollow">http://en.wikipedia.org/wiki/Mandelbrot_set#Optimizations</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127443</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127443</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:46:49 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:53:20 GMT]]></title><description><![CDATA[<p>Mit Assembler könnte man das in soweit noch optimieren, dass du darauf schaust, dass es möglichst wenig Cache misses gibt und möglichst nur mit Registern arbeitest. Da sind Compiler üblicherweise nicht so gut, weil es dazu oftmals ein Umordnen der Anweisungen erfordert, was nicht immer (für einen Compiler) offensichtlich äquivalent ist.</p>
<p>Du könntest auch mal versuchen mit SSE und ähnlichen Erweiterungen noch was rauszuholen.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a><br />
Compiler sind relativ schwache optimierer für solche kleine Sachen, weil sie so verdammt konservativ sind (ist auch gut so). Wenn man solche Stückchen von Auge anschaut kann man da durchaus recht viel rausholen, wenn man sich ein wenig mit der Arbeitsweise von CPUs auskennt (Caching, Pipelineing, Data dependencies, forwarding, aliasing etc.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127444</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:53:20 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:51:25 GMT]]></title><description><![CDATA[<p>wie groß kann numIterations werden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127449</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127449</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:51:25 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:54:31 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Du könntest auch mal versuchen mit SSE und ähnlichen Erweiterungen noch was rauszuholen.</p>
</blockquote>
<p>Wenn ich im Leben eines gelernt habe, dann dass SSE-Intrinsics bei so Einzelrechnungen eher bremsen. In der Regel machen die Compiler hier wirklich das beste was geht. Eventuell kannst du durch geschickte Compileroptionen noch mal ordentlich was rausholen (5-10%). Viele Leute wissen gar nicht, wie sie das Optimieren optimieren können <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> .</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a><br />
Compiler sind relativ schwache optimierer für solche kleine Sachen, weil sie so verdammt konservativ sind (ist auch gut so). Wenn man solche Stückchen von Auge anschaut kann man da durchaus recht viel rausholen, wenn man sich ein wenig mit der Arbeitsweise von CPUs auskennt (Caching, Pipelineing, Data dependencies, forwarding, aliasing etc.)</p>
</blockquote>
<p>Also ich habe das letzte halbe Jahr damit verbracht, herauszufinden, dass dies nicht so ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127451</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127451</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:54:31 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:55:24 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>Du könntest auch mal versuchen mit SSE und ähnlichen Erweiterungen noch was rauszuholen.</p>
</blockquote>
<p>Wenn ich im Leben eines gelernt habe, dann dass SSE-Intrinsics bei so Einzelrechnungen eher bremsen. In der Regel machen die Compiler hier wirklich das beste was geht. Eventuell kannst du durch geschickte Compileroptionen noch mal ordentlich was rausholen (5-10%). Viele Leute wissen gar nicht, wie sie das Optimieren optimieren können <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> .</p>
</blockquote>
<p>Hmm. Natürlich darf man das nicht einfach stupide ersetzen. Das bringt dann nix, aber wenn man sinnvoll die Anweisungen aufteilen kann, sollte das doch einiges bringen. Man muss natürlich sehr gut darüber nachdenken was man machen kann (vlt. bringts am Ende wirklich nix, wenn es zu viele Abhängigkeiten hat).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127452</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127452</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:55:24 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 08:56:59 GMT]]></title><description><![CDATA[<p>Da du schon an Inline-Assembler denkst: Hast du dir mal den generierten Code angeguckt?</p>
<p>Ansonsten:<br />
Du berechnest die Quadrate pro Iteration zweimal. Falls der Compiler das nicht optimiert, immerhin ist der Wert iterationsübergreifend, dann könntest du dafür zwei extra Variablen einführen:</p>
<pre><code class="language-cpp">int calculateNumIterations(mandelType x, mandelType y)
{
    mandelType x1=0, x2=0, y1=0, x1squared = 0, y1squared = 0;
    for(int i = 0; i &lt; numIterations; ++i)
    {
        x2 = x1squared - y1squared + x;
        y1 = 2*x1*y1 + y;
        y1squared = y1*y1;
        x1 = x2;
        x1squared = x1*x1;
        if(x1squared  + y1squared &gt; 4)
        {
            return i;
        }
    }
    return numIterations;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2127454</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127454</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 05 Oct 2011 08:56:59 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 09:00:54 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a><br />
Compiler sind relativ schwache optimierer für solche kleine Sachen, weil sie so verdammt konservativ sind (ist auch gut so). Wenn man solche Stückchen von Auge anschaut kann man da durchaus recht viel rausholen, wenn man sich ein wenig mit der Arbeitsweise von CPUs auskennt (Caching, Pipelineing, Data dependencies, forwarding, aliasing etc.)</p>
</blockquote>
<p>Also ich habe das letzte halbe Jahr damit verbracht, herauszufinden, dass dies nicht so ist.</p>
</blockquote>
<p>Also ich habe schon sehr einfache Strukturen gesehen, die sehr gut optimierbar waren, wenn man nur ein paar Anweisungen vertauscht. Wenn man dem nicht bewusst ist, dann verliert man da Power. Kann gut sein, dass du da einiges mehr Erfahrung hast, aber finde es halt auch plausibel, dass man da im feinen einiges besser von Hand optimieren kann als es ein Compiler überhaupt darf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127456</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127456</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 09:00:54 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 09:10:37 GMT]]></title><description><![CDATA[<p>Die einzelnen Pixel sind völlig unabhängig voneinander. D.h. du kannst mit SSE/AVX und Multithreading potentiell viel rausholen. Gegen eine Lösung im FragmentShader hat die CPU aber sicher keine Chance...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127458</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127458</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Wed, 05 Oct 2011 09:10:37 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 09:15:24 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Also ich habe schon sehr einfache Strukturen gesehen, die sehr gut optimierbar waren, wenn man nur ein paar Anweisungen vertauscht.</p>
</blockquote>
<p>Dann musst du dem Compiler erlauben Operationen zu vertauschen. Beispiel beim Gcc -Ofast</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127461</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127461</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 05 Oct 2011 09:15:24 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 09:24:29 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>Also ich habe schon sehr einfache Strukturen gesehen, die sehr gut optimierbar waren, wenn man nur ein paar Anweisungen vertauscht.</p>
</blockquote>
<p>Dann musst du dem Compiler erlauben Operationen zu vertauschen. Beispiel beim Gcc -Ofast</p>
</blockquote>
<p>Sicher eine Möglichkeit, aber es gibt ja Optimierungen, die eigentlich nicht äquivalent sind, aber dann halt im jeweiligen Fall doch (weil man halt gewisse Umstände kennt, die ein Compiler nicht kenne kann) und da kann man auch mit solchen Einstellungen nichts gewinnen.<br />
Auf die schnelle kann ich kein gutes Beispiel bringen, aber ich denke ihr wisst was ich meine.<br />
Natürlich sollte man zuerst den Compiler ausreizen, aber dann kann es sich schon auch lohnen den generierten Code sehr gut anzuschauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127467</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127467</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 09:24:29 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 10:36:35 GMT]]></title><description><![CDATA[<p>Also erstmal zu multithreading:<br />
Das ganze läuft schon multithreaded. Die schleife wird für jeden Pixel aufgerufen.<br />
Ich habe den Bildschirm in &quot;Tiles&quot; aufgeteilt (je ca. 100x100 Pixel). Dann überegebe ich einem Threadpool die ganzen tiles zum rendern.</p>
<p>NumIterations ist eine kompilezeitkonstante und hat normalerweise einen wert von ca. 500-3000. (Atm verwende ich 800).</p>
<p>Wie wäre es rein theoretisch, wenn man die ganze schleife &quot;entrollen&quot; würde?<br />
Würde das eher schaden oder was bringen? Der code wird dadurch größer, was vermutlich schlecht für den cache ist, aber dann braucht man keine explizite schleife mehr.</p>
<p>Und zum quadrat zweimal berechnen: Ich glaube das geht nicht besser, weil sich die werte zwischendrin auch ändern? Aber ich gucks mir gleich nochmal genau an.</p>
<p>Ok danke für eure hilfe. Aber vermutlich werd ichs dann so belassen, weil ich mich mit asm nicht auskenne und das vermutlich auch nicht soooo viel bringen würde.</p>
<p>Edit: Ich benutz übrigens MSVC. Hab einfach release mode genommen. Was kann man denn da noch so umstellen, was was bringen könnte?</p>
<p>Edit2: Profiler hab ich benutzt (den vom visual studio 2010), der zeigt mir aber immer an das 99% cpu zeit auf einen slot (ich benuitze qt) draufgehen. Aber das zeigt er auch an wenn in dem slot gar kein code steht.<br />
Aber das liegt definitiv an der schleife. Das ist das Herzstück des algorithmus und wird für jeden Pixel aufgerufen.<br />
Setze ich die anzahl der iterationen runter, dann läuft das problem VIEL schneller. Es skaliert also direkt mit der anzahl der iterationen (~linear nehme ich an).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127493</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127493</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Wed, 05 Oct 2011 10:36:35 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 10:44:12 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>Und zum quadrat zweimal berechnen: Ich glaube das geht nicht besser, weil sich die werte zwischendrin auch ändern?</p>
</blockquote>
<p>Tun sie ja nicht. Klar, innerhalb der Iteration schon, aber nicht von einer Iteration zur nächsten: Die Quadrate in deiner Abbruchbedingung sind die gleichen wie die am Anfang der nächsten Iteration.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127498</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 05 Oct 2011 10:44:12 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 10:57:19 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<p>Wie wäre es rein theoretisch, wenn man die ganze schleife &quot;entrollen&quot; würde?<br />
Würde das eher schaden oder was bringen? Der code wird dadurch größer, was vermutlich schlecht für den cache ist, aber dann braucht man keine explizite schleife mehr.</p>
</blockquote>
<p>Loop unrolling beherrschen Compiler eigentlich recht gut, weil es klar ist, wie man das machen muss.</p>
<p>Aber kannst es ja mal testen. Ich vermute aber, dass es nichts bringt, wenn du das von Hand selber machst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127506</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127506</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 10:57:19 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 11:14:22 GMT]]></title><description><![CDATA[<p>Sind compiler denn so &quot;verrückt&quot; und unrollen loops die von 0 bis ~1000 gehen?<br />
Bzw ist sowas gang und gebe oder ist das eher schlecht, weils den code zu sehr aufbläht?</p>
<p>Das mit den quadraten bau ich dann evtl. gleich mal ein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127516</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127516</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Wed, 05 Oct 2011 11:14:22 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 11:24:06 GMT]]></title><description><![CDATA[<p>Ne, kein Compiler wird den loop 1000 fach ausrollen.<br />
Aber vielleicht 4-fach oder so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127519</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127519</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 05 Oct 2011 11:24:06 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 14:56:35 GMT]]></title><description><![CDATA[<p>Auf Loopunrolling seitens des Compilers würde ich wegen des ifs nicht gerade setzen.<br />
Man kann es manuell machen und die Tatsache ausnützen, dass die Abbruchbedingung (erst einmal erreicht) auch nach weiteren Iterationen wahr bleiben müsste.</p>
<p>Ein Test auf zwei verschiedenen Prozessoren mit gcc 4.6 (Generierung eines 1680x1050-Bildes im Bereich (-2.1 | -1.3) bis (0.8 | 1.3) mit numIterations=1000):<br />
<a href="http://94.23.22.190/etc/phenom-ii-x4.png" rel="nofollow">http://94.23.22.190/etc/phenom-ii-x4.png</a><br />
<a href="http://94.23.22.190/etc/atom.png" rel="nofollow">http://94.23.22.190/etc/atom.png</a></p>
<p>Noch einmal mit der auf Wikipedia beschriebenen Optimierung:<br />
<a href="http://94.23.22.190/etc/phenom-ii-x4-opt.png" rel="nofollow">http://94.23.22.190/etc/phenom-ii-x4-opt.png</a><br />
<a href="http://94.23.22.190/etc/atom-opt.png" rel="nofollow">http://94.23.22.190/etc/atom-opt.png</a></p>
<p>Ich würde für 5-faches Unrolling plädieren.<br />
Ob es Unterschiede beim MSVC gibt, würde mich auch interessieren, allerdings muss ich mein Testsystem vorher noch um Wine-Unterstützung erweitern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127605</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127605</guid><dc:creator><![CDATA[Athar]]></dc:creator><pubDate>Wed, 05 Oct 2011 14:56:35 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 15:30:43 GMT]]></title><description><![CDATA[<p>Athar schrieb:</p>
<blockquote>
<p>Man kann es manuell machen und die Tatsache ausnützen, dass die Abbruchbedingung (erst einmal erreicht) auch nach weiteren Iterationen wahr bleiben müsste.</p>
</blockquote>
<p>Arrr, zu langsam <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="🙂"
    /><br />
Genau das ist mir auch gerade eingefallen, wollte ich gerade vorschlagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127620</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 05 Oct 2011 15:30:43 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 15:36:18 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Sicher eine Möglichkeit, aber es gibt ja Optimierungen, die eigentlich nicht äquivalent sind, aber dann halt im jeweiligen Fall doch (weil man halt gewisse Umstände kennt, die ein Compiler nicht kenne kann) und da kann man auch mit solchen Einstellungen nichts gewinnen.<br />
Auf die schnelle kann ich kein gutes Beispiel bringen, aber ich denke ihr wisst was ich meine.</p>
</blockquote>
<p>Athar schrieb:</p>
<blockquote>
<p>Man kann es manuell machen und die Tatsache ausnützen, dass die Abbruchbedingung (erst einmal erreicht) auch nach weiteren Iterationen wahr bleiben müsste.</p>
</blockquote>
<p>Danke für das gute Beispiel! <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>
<p>Perfect branch predictor gibts leider (noch) nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127623</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127623</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Oct 2011 15:36:18 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 15:44:17 GMT]]></title><description><![CDATA[<p>Ich steh wohl grad auf dem Schlauch. Was genau bringt es, dass die Abbruchbedingung erfüllt bleibt, wenn sie es einmal ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127629</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127629</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 05 Oct 2011 15:44:17 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 15:52:23 GMT]]></title><description><![CDATA[<p>Dadurch kannst du das machen</p>
<pre><code>loop {
    save_state();
    step();
    step();
    step();
    step();
    step();
    if (cond) {
        restore_state();
        loop {
            step();
            if (cond)
                return;
        }
    }
}
</code></pre>
<p>D.h. du musst nur pro N Steps 1x testen.<br />
Sonst könntest du zwar den Loop ausrollen, aber müsstest trotzdem nach jedem Step testen.</p>
<p>(Alternativ zu save/restore/repeat könnte man auch ein Backlog der Z Werte schreiben, dann müsste man in der 2. Schleife nur den Test wiederholen, aber nix mehr rechnen)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127634</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127634</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 05 Oct 2011 15:52:23 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 15:52:17 GMT]]></title><description><![CDATA[<p>Oh ja, danke. Wie gesagt, Schlauch... <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/2127635</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127635</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 05 Oct 2011 15:52:17 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 17:05:57 GMT]]></title><description><![CDATA[<p>Interessanterweise bringen die eingesparten Vergleiche und Multiplikationen weniger als erwartet. Möglicherweise deswegen, weil die Werte schnell +inf erreichen und sich die CPU evtl. bei Berechnungen mit diesen schwertut (geraten, aber unwahrscheinlich). Hat vermutlich eher mit dem Cache bzw. Sprungweiten zu tun.</p>
<p>Der Atom profitiert zwar von den ausgelassenen Vergleichen, der Phenom aber nicht unbedingt. Hier mit Vergleich nach jeder Iteration:</p>
<p><a href="http://94.23.22.190/etc/phenom-ii-x4-opt-f.png" rel="nofollow">http://94.23.22.190/etc/phenom-ii-x4-opt-f.png</a><br />
<a href="http://94.23.22.190/etc/atom-opt-f.png" rel="nofollow">http://94.23.22.190/etc/atom-opt-f.png</a></p>
<p>Es bleibt aber dabei, dass 5-faches Unrolling mit einem Vergleich alle 5 Iterationen insgesamt am besten zu sein scheint.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127678</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127678</guid><dc:creator><![CDATA[Athar]]></dc:creator><pubDate>Wed, 05 Oct 2011 17:05:57 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Wed, 05 Oct 2011 20:08:19 GMT]]></title><description><![CDATA[<p>Vielen Dank, dass du dir so viel Mühe machst!<br />
Soll ich dann versuchen beim MSVC das unrolling zu konfigurieren oder sowas oder manuell machen?</p>
<p>Ich fange gerade auch an mit der fragment-shader implementierung, allerdings gibts da ein paar schwierigkeiten, weil ich ja auch fixed point einbaun will.<br />
Ich brauch da operatinen wie z.B. bitweises und, dass die Graka von meinem laptop leider nicht kann, deswegen muss ich das dann leider alles am Desktop-PC entwickeln.</p>
<p>Auch unterstützt glsl keine 16bit-datentypen.</p>
<p>Meine derzeitige fixed-point-planung sieht so aus:</p>
<p>(Wird dann in glsl wohl geringfügig anders aussehen)</p>
<pre><code class="language-cpp">const int numMantissaInts = 8; //änderbar

struct FixedPoint
{
   uint data[1 + numMantissaInts]; //bei glsl heißts uint und nicht unsigned int
};

//oder einfach:
typedef uint FixedPoint[1 + numMantissa]; //ist die syntax (bei c++) so richtig?
// Glsl hat afaik eh keine typedefs, 
//aber ich kanns dann ja einfach das array so verwenden, 
//oder die struct.
</code></pre>
<p>das erste element des arrays hat eine besondere bedeutung:<br />
es speichert gleichzheitig das vorzeichen und die zahlen vorm komma.<br />
Ein bereich von -16..16 als ganzzahlanteil reicht völlig und dazu ein flag. der rest bleibt unenutzt.</p>
<p>Jeder uint danach steht jeweils für die nächsten 32 nachkommastellen (im 2er system).</p>
<p>Beim Berechnen von addition/multiplikation werde ich dann mit einer schleife von hinten nach vorne dadurch gehen.<br />
Dabei werde ich dann jeden uint in 2 teile teilen um einen überlauf zu vermeiden.</p>
<p>Also mal angedeutet als beispiel:</p>
<pre><code class="language-cpp">uint x1, x2;
//x1 und x2 werden addiert
uint x11 = (x1 &amp; 0xFFFF0000u) &gt;&gt; 16;
uint x12 = x1 &amp; 0x0000FFFFu;
uint x21 = (x2 &amp; 0xFFFF0000u) &gt;&gt; 16;
uint x22 = x2 &amp; 0x0000FFFFu;

uint sum1 = x12 + x22;
uint uebertrag1 = (sum1 &amp; 0xFFFF0000u) &gt;&gt; 16;
uint sum2 = x11 + x12 + uebertrag1;
uint uebertrag2 = (sum2 &amp; 0xFFFF0000u) &gt;&gt; 16; // wird für die stellen weiter vorne 
//verwendet (die im moment nicht beachtet werden)

uint sum = (sum1 &amp; 0x0000FFFFu) | ((sum 2 &amp; 0x0000FFFFu) &lt;&lt; 16);
</code></pre>
<p>Ich hoffe, dass das prinzip nachvollziehbar ist, dass ich keine fehler eingebaut hab und vor allem, dass moderne Grafikkarten bitweise operationen performant durchführen können.<br />
Das hat zwar ziemlichen overhead, aber ich wüsste nicht, wie ich fixed-point-arithmetik besser implementieren kann.<br />
Hat jemand (verbesserungs-)Vorschläge?</p>
<p>Edit: Nur um verwirrungen vorzubeugen: Auch wenn die variablen hier ähnlich wie bei der Mandelbrotformel heißen - hier geht es nicht um berechnung dieser formel, sondern nur um die realisierung von fixed point arithmetik.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2127688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2127688</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Wed, 05 Oct 2011 20:08:19 GMT</pubDate></item><item><title><![CDATA[Reply to Kann man das noch optimieren? (Mandelbrot-Berechnung) on Thu, 15 Mar 2012 11:51:59 GMT]]></title><description><![CDATA[<p>Ich beleb den Thread mal wieder, weil ich mich inzwischen wieder damit beschäftige.</p>
<p>Ich habe jetzt eine Implementierung geschrieben, die MPI und OpenMP verwendet und auf einem Cluster ausgegführt werden soll.<br />
Außerdem verwende ich die MPIR bibliothek für genauere floating-point-berechnungen.</p>
<p>Auch hier will ich wieder kräftig optimieren <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>
<p>Es gibt da jetzt ein paar Sachen, die ich im Moment untersuche:</p>
<p>1. In der Anleitung zu MPIR steht, dass das schneller läuft, wenn man es auf die richtige CPU konfiguriert, da dann optimierter asm-code benutzt werden kann. (Siehe <a href="http://www.mpir.org/mpir-2.5.1.pdf" rel="nofollow">http://www.mpir.org/mpir-2.5.1.pdf</a> Seite 11)<br />
Dort wird angedeutet, wie man das einstellen kann.<br />
Bisher habe ich einfach ./configure und dann make gemacht.<br />
Ich habe ein bischen recherchiert und glaube, dass das Cluster die 'core' Architektur hat (es sind dort Intel Xeon E5450 @ 3.00GHz verbaut).<br />
Allerdings weiß ich nicht, wie ich dem &quot;configure&quot;-Programm sage, welche Architektur er nehmen soll.<br />
Mit</p>
<pre><code>./configure core
</code></pre>
<p>funktioniert es nicht.<br />
dann habe ich</p>
<pre><code>./configure march=core
</code></pre>
<p>versucht, das klappt sogar.<br />
Allerdings habe ich dann testweise mal versucht:</p>
<pre><code>./configure march=fgiosdhiogdhidvshisdf
</code></pre>
<p>und das ging auch, also glaub ich eig nicht, dass das geklappt hat mit dem core.</p>
<p>Auf der Seite davor steht etwas von:<br />
Cross Compilation, ‘--host=CPU-VENDOR-OS’<br />
Ich denke, dass das evtl. das richtige ist, bin mir aber nicht sicher, was ich dann als vendor und os angeben muss.<br />
Habt ihr eine Idee, wie das geht?</p>
<p>2. Kann ich vielleicht mit den Compilerflags noch was rausholen? Im moment kompiliere ich mit</p>
<pre><code>mpicc Main.cpp Worker.cpp Master.cpp Common.cpp -I mpir-2.5.0 -L mpir-2.5.0/.libs -lmpir -Wall -O3 -fopenmp -fomit-frame-pointer -o mandelbrot.out
</code></pre>
<p>Wobei mpicc ein intelcompiler ist.</p>
<p>3. Ich werde nachher mal einen Profiler für parallele Programme drüber laufen lassen, aber ich bin nach wie vor der Meinung, dass die Funktion &quot;CalculateNumIterations&quot; das bottleneck ist.<br />
Ich habe diese auch schon optimiert, so das temporaries vermieden werden und berechnungen (quadrat) nicht mehrfach gemacht werden.<br />
Das hat auch ganzschön was gebracht, die Laufzeit eines Beispielszenarios hat sich von 357.603s auf 97,23s reduziert.</p>
<p>Der aktuelle Code dazu sieht so aus (wobei mandelType ein typedef für mpf_class ist, was quasi ein BigFloat ist, den ich im Moment auf mindestens 512 bit genauigkeit eingestellt habe).</p>
<pre><code class="language-cpp">int CalculateNumIterations(const mandelType&amp; x, const mandelType&amp; y)
{
	mandelType x1 = x, y1 = y;
	mandelType xQuad = x * x, yQuad= y * y;
	for(int i = 0; i &lt; numIterations; ++i)
	{	
		y1 *= x1;
		y1 *= 2;
		y1 += y;

		x1 = xQuad;
		x1 -= yQuad;
		x1 += x;

		xQuad = x1 * x1;
		yQuad = y1 * y1;

		if(xQuad + yQuad  &gt; 4)
		{
			return i;
		}
	}
	return numIterations;
}
</code></pre>
<p>Hinweis: numIterations hat typischerweise einen Wert von 1000-10000. Mehr als 1 Million wird es so gut wie sicher nicht.<br />
Und bitte dran denken, dass das keine normalen doubles sind, sondern klassen mit überladenen operatoren.</p>
<p>Seht ihr da noch optimierungspotenzial?</p>
<p>4. Die Ausgabedatei wird inzwischen ziemlich groß (z.B. 100 MB oder mehr), aber wenn ich winrar dadrauf loslasse, bleibt meist &lt; 1MB übrig. Deswegen habe ich mir überlegt, die daten am besten schon komprimiert in die Ausgabedatei zu schreiben, dan dauert das rüberkopieren vom Cluster auf meinen Rechner auch nicht mehr solang. Dabei wäre es gut, wenn die komprimiering &quot;on the fly&quot; erfolgen kann, also das ich nicht erst alle Daten im Speicher haben muss und dann alles auf einmal komprimiere, sondern das das &quot;inkrementell&quot; passieren kann.<br />
Ich habe mir überlegt, evtl. mal die zlib anzugucken, aber erstens weiß ich nicht, ob die eine solche inkrementelle komprimierung unterstützt und außerdem ist es immer extraaufwand mit externen Bibliotheken.<br />
Meine andere Idee ist, selbst eine LZW Komprimierung zu implementieren. Das verfahren ich recht einfach und ich habe das schonmal in java implementiert. Außerdem kann das auch inkrementell eingestzt werden. Allerdings bin ich mir unsicher, inwiefern das gute Kompressionsraten bringt.<br />
Kennt ihr da vielleicht noch eine gute Alternative?<br />
Die Ausgabedateien sind im Moment einfach eine lange reihe von zahlen die im Werteberech [0, numIterations] liegen (wobei numIterations so ca. 1000 - allerallerhöchstens 1Million groß ist), die mit Komma getrennt sind.<br />
Falls möglich, will ich die komprimierten dateien auch mit anderen Programmiersprachen verarbeiten können. Beim LZW wäre das möglich, weil ich den sowieso selbst implementieren würde.</p>
<p>Vielen Dank für eure Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2191857</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2191857</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Thu, 15 Mar 2012 11:51:59 GMT</pubDate></item></channel></rss>