<?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[Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich beschäftige mich mit threads, genauer mit der boost library, und habe zur Übung eine for-Schleife in zwei for-Schleifen aufgeteilt, die dann jeweils von einem eigenen Thread berechnet werden.</p>
<p>Die singlethreaded Variante sieht so aus:</p>
<pre><code>#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  boost::uint64_t sum = 0; 
  for (long i = 0; i &lt; 1000000000; ++i) 
    sum += i; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
}
</code></pre>
<p>Die multithreaded Variante so:</p>
<pre><code>#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;boost/thread.hpp&gt;

#include &lt;iostream&gt; 

#ifndef BOOST_HAS_THREADS
#error &quot;Error: No thread support&quot;
#endif

boost::uint64_t sum1; 
boost::uint64_t sum2; 

void thread1() 
{ 
    for (long i = 0; i &lt; 500000000; ++i) 
      sum1 += i; 
}

void thread2() 
{ 
    for (long i = 500000000; i &lt; 1000000000; ++i) 
      sum2 += i; 
}

int main() 
{ 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  boost::thread t1(thread1); 
  boost::thread t2(thread2); 

  t1.join(); 
  t2.join(); 

  boost::uint64_t sum = sum1 + sum2; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
}
</code></pre>
<p>Wie man sieht wird die Laufzeit gemessen. Was mich verwundert sind die Ergebnisse:</p>
<p>Bei -O0:<br />
singlethreaded: 3,5 s<br />
multithreaded: 7 s</p>
<p>Bei -O1/-O2:<br />
singlethreaded: 1,4 s/ 1,0 s<br />
multithreaded: ca. 500 µs</p>
<p>Wie kann das sein, dass bei -O0 die multitrheaded Variante deutlich langsamer ist (beide Cores die ich habe sind voll ausgelastet), bei -O1 bzw. -O2 die multitrheaded Variante aufeinmal rasen schnell mit nur ca. 500 Mikrosekunden abläuft?</p>
<p>Wie verhält es sich bei euch?</p>
<p>Gruß Stefan</p>
<p>PS: Ich habe einen Athlon 64 X2 4200+ und Linux</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/264222/parallelisierte-for-schleife-mit-boost-thread-führt-zu-unglaubwürdigem-gewinn</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 04:59:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/264222.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 04 Apr 2010 16:10:54 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Sun, 04 Apr 2010 16:10:54 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich beschäftige mich mit threads, genauer mit der boost library, und habe zur Übung eine for-Schleife in zwei for-Schleifen aufgeteilt, die dann jeweils von einem eigenen Thread berechnet werden.</p>
<p>Die singlethreaded Variante sieht so aus:</p>
<pre><code>#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  boost::uint64_t sum = 0; 
  for (long i = 0; i &lt; 1000000000; ++i) 
    sum += i; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
}
</code></pre>
<p>Die multithreaded Variante so:</p>
<pre><code>#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;boost/thread.hpp&gt;

#include &lt;iostream&gt; 

#ifndef BOOST_HAS_THREADS
#error &quot;Error: No thread support&quot;
#endif

boost::uint64_t sum1; 
boost::uint64_t sum2; 

void thread1() 
{ 
    for (long i = 0; i &lt; 500000000; ++i) 
      sum1 += i; 
}

void thread2() 
{ 
    for (long i = 500000000; i &lt; 1000000000; ++i) 
      sum2 += i; 
}

int main() 
{ 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  boost::thread t1(thread1); 
  boost::thread t2(thread2); 

  t1.join(); 
  t2.join(); 

  boost::uint64_t sum = sum1 + sum2; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
}
</code></pre>
<p>Wie man sieht wird die Laufzeit gemessen. Was mich verwundert sind die Ergebnisse:</p>
<p>Bei -O0:<br />
singlethreaded: 3,5 s<br />
multithreaded: 7 s</p>
<p>Bei -O1/-O2:<br />
singlethreaded: 1,4 s/ 1,0 s<br />
multithreaded: ca. 500 µs</p>
<p>Wie kann das sein, dass bei -O0 die multitrheaded Variante deutlich langsamer ist (beide Cores die ich habe sind voll ausgelastet), bei -O1 bzw. -O2 die multitrheaded Variante aufeinmal rasen schnell mit nur ca. 500 Mikrosekunden abläuft?</p>
<p>Wie verhält es sich bei euch?</p>
<p>Gruß Stefan</p>
<p>PS: Ich habe einen Athlon 64 X2 4200+ und Linux</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877521</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877521</guid><dc:creator><![CDATA[stefan-tiger]]></dc:creator><pubDate>Sun, 04 Apr 2010 16:10:54 GMT</pubDate></item><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Sun, 04 Apr 2010 16:40:00 GMT]]></title><description><![CDATA[<p>Die Ergebnisse der beiden Schleifen sind konstant und sie haben keine Nebeneffekte. Vermutlich kann der Compiler sie wegoptimieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877532</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877532</guid><dc:creator><![CDATA[Registrierter Troll]]></dc:creator><pubDate>Sun, 04 Apr 2010 16:40:00 GMT</pubDate></item><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Sun, 04 Apr 2010 18:01:34 GMT]]></title><description><![CDATA[<p>Registrierter Troll schrieb:</p>
<blockquote>
<p>Die Ergebnisse der beiden Schleifen sind konstant und sie haben keine Nebeneffekte. Vermutlich kann der Compiler sie wegoptimieren.</p>
</blockquote>
<p>denke ich auch - allerdings ist es komisch, dass er nicht auch die single-thread-variante so optimieren kann... müsste man mal ein wenig im asm-code rumstochern, um das erklären zu können...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877573</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877573</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sun, 04 Apr 2010 18:01:34 GMT</pubDate></item><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Sun, 04 Apr 2010 18:22:51 GMT]]></title><description><![CDATA[<p>Ich hab die gcc Versionen 4.1.2 und 4.3.4. Das obige Laufzeitverhalten betrifft die 4.3.4.</p>
<p>Da wird tatsächlich die singlethreaded Variante nicht optimiert bzw. die Schleife bei der multithreaded Variante einfach wegoptimiert.</p>
<p>Die Version 4.1.2 optimiert auch bei der singlethreaded Variante die Schleife weg.</p>
<p>Leider ist das Verhalten ohne Optimierung (-O0) auch bei 4.1.2 so wie oben angegeben. Ich hab noch die Schleife der singlethreaded Variante in eine Funktion calc() gepackt die sum als globale Variable befüllt.</p>
<p>Ich habe einen Dump mit -O0 und der 4.1.2 gemacht und folgendes gefunden:</p>
<p>singlethreaded:</p>
<pre><code>void calc(void)
  418868:   55                      push   %rbp
  418869:   48 89 e5                mov    %rsp,%rbp
{
  for (long i = 0; i &lt; 1000000000; ++i) 
  41886c:   48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
  418873:   00 
  418874:   eb 19                   jmp    41888f &lt;_Z4calcv+0x27&gt;
    sum += i;
  418876:   48 8b 05 83 6e 21 00    mov    0x216e83(%rip),%rax        # 62f700 &lt;sum&gt;
  41887d:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
  418881:   48 01 d0                add    %rdx,%rax
  418884:   48 89 05 75 6e 21 00    mov    %rax,0x216e75(%rip)        # 62f700 &lt;sum&gt;

boost::uint64_t sum = 0;

void calc(void)
{
  for (long i = 0; i &lt; 1000000000; ++i) 
  41888b:   48 ff 45 f8             incq   -0x8(%rbp)
  41888f:   48 81 7d f8 ff c9 9a    cmpq   $0x3b9ac9ff,-0x8(%rbp)
  418896:   3b 
  418897:   7e dd                   jle    418876 &lt;_Z4calcv+0xe&gt;
    sum += i;
}
  418899:   c9                      leaveq 
  41889a:   c3                      retq   
  41889b:   90                      nop
</code></pre>
<p>multithreaded:</p>
<pre><code>void thread1() 
  41b688:   55                      push   %rbp
  41b689:   48 89 e5                mov    %rsp,%rbp
{ 
    for (long i = 0; i &lt; 500000000; ++i) 
  41b68c:   48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
  41b693:   00 
  41b694:   eb 19                   jmp    41b6af &lt;_Z7thread1v+0x27&gt;
      sum1 += i; 
  41b696:   48 8b 05 43 91 21 00    mov    0x219143(%rip),%rax        # 6347e0 &lt;sum1&gt;
  41b69d:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
  41b6a1:   48 01 d0                add    %rdx,%rax
  41b6a4:   48 89 05 35 91 21 00    mov    %rax,0x219135(%rip)        # 6347e0 &lt;sum1&gt;
boost::uint64_t sum2; 

void thread1() 
{ 
    for (long i = 0; i &lt; 500000000; ++i) 
  41b6ab:   48 ff 45 f8             incq   -0x8(%rbp)
  41b6af:   48 81 7d f8 ff 64 cd    cmpq   $0x1dcd64ff,-0x8(%rbp)
  41b6b6:   1d 
  41b6b7:   7e dd                   jle    41b696 &lt;_Z7thread1v+0xe&gt;
      sum1 += i; 
}
  41b6b9:   c9                      leaveq 
  41b6ba:   c3                      retq   
  41b6bb:   90                      nop
</code></pre>
<p>Das verblüffende: Der Code ist genau gleich, jedoch lasted die singlethreaded variante einen Core für ca. 3,5 sek aus während die multithreaded Variante beide Cores für ca. 7 sek auslastet.</p>
<p>Das ist total unlogisch und ich kann es mir noch nicht erklären.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877583</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877583</guid><dc:creator><![CDATA[stefan-tiger]]></dc:creator><pubDate>Sun, 04 Apr 2010 18:22:51 GMT</pubDate></item><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Sun, 04 Apr 2010 18:25:31 GMT]]></title><description><![CDATA[<p>Eine mögliche Erklärung wäre: das Anlegen von Threads dauert bei -O0 so lange, dass der Gewinn den man durch das parallele Abarbeiten bekäme dadurch wieder zunichte gemacht wird. Würde aber bedeuten ein Thread anzulegen dauert dann 2-3 sek.</p>
<p>Wie finde ich das raus. Jemand ne Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877585</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877585</guid><dc:creator><![CDATA[stefan-tiger]]></dc:creator><pubDate>Sun, 04 Apr 2010 18:25:31 GMT</pubDate></item><item><title><![CDATA[Reply to Parallelisierte for-Schleife mit boost::thread führt zu unglaubwürdigem Gewinn on Mon, 05 Apr 2010 08:08:09 GMT]]></title><description><![CDATA[<p>Ich habe eine &quot;Lösung&quot; die dafür sorgt, dass der Compiler die Schleifen nichtmehr wegoptimiert (obwohl er es noch könnte). Ich habe einfach in den Schleifenkopf Variablen statt Konstanter Zahlen eingefügt:</p>
<p>Ich habe dann auch noch die Anzahl verzehnfacht!</p>
<p>singlethreaded:</p>
<pre><code class="language-cpp">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;iostream&gt; 

boost::uint64_t sum = 0;
long n = 0;

void calc(void)
{
  for (long i = 0; i &lt; n; ++i) 
    sum += i;
}

int main() 
{ 
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  n = 10000010000;

   calc();

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
}
</code></pre>
<p>multithreaded:</p>
<pre><code class="language-cpp">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;boost/thread.hpp&gt;

#include &lt;iostream&gt; 

#ifndef BOOST_HAS_THREADS
#error &quot;Error: No thread support&quot;
#endif

boost::uint64_t sum1; 
boost::uint64_t sum2; 
long n1 = 0;
long n2 = 0;

void thread1() 
{ 
    for (long i = 0; i &lt; n1; ++i) 
      sum1 += i; 
}

void thread2() 
{ 
    for (long i = n1; i &lt; n2; ++i) 
      sum2 += i; 
}

int main() 
{ 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  n1 =  5000010000;
  n2 = 10000010000;

  boost::thread t1(thread1); 
  boost::thread t2(thread2); 

  t1.join(); 
  t2.join(); 

  boost::uint64_t sum = sum1 + sum2; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
  std::cout &lt;&lt; &quot;main begin&quot; &lt;&lt; std::endl;
}
</code></pre>
<p>Ergebnis der für &quot;sum&quot;: 13106611847630891768</p>
<p>Laufzeit-Ergebnisse mit g++ 4.1.2 und -O2:</p>
<p>singletrheaded: 9,4 sek<br />
multithreaded; 5 sek</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1877699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1877699</guid><dc:creator><![CDATA[stefan-tiger]]></dc:creator><pubDate>Mon, 05 Apr 2010 08:08:09 GMT</pubDate></item></channel></rss>