Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Under what scenarios can running a multithreaded app on a single core destroy performance?</p> <p>What about setting the affinity of a multithreaded app to only use one core?</p> </blockquote> <p>In both cases, the answer is much the same. If your program is running on a single core, then only one thread runs at a time. And that means that any time one thread has to wait for another, you need the OS to perform a context switch, which is a fairly expensive operation. </p> <p>When run on multiple cores, there's a decent chance that the two threads that need to interact will both be running simultaneously, and so the OS won't need to perform a context switch for your code to proceed.</p> <p>So really, code which requires a lot of inter-thread synchronization is going to run slower on a single core.</p> <p>But you can make it worse. A spinlock, or any kind of busy-waiting loop will absolutely destroy performance. And it should be obvious why. You can only run one thread at a time, so if you need a thread to wait for some event, you should tell the OS to put it to sleep immediately, so that another thread can run.</p> <p>If instead you just do some "while condition is not met, keep looping" busy loop, you're keeping the thread running, even though it has nothing to do. It'll continue looping *until the OS decides that its time is up, and it schedules another thread. (And if the thread doesn't get blocked by something, it'll typically be allowed to run for upwards of 10 milliseconds at a time.)</p> <p>In multithreaded programming in general, and *<em>especially</em> multithreaded code running on a single core, you need to play nice, and not hog the CPU core more than necessary. If you have nothing sensible to do, allow another thread to run.</p> <p>And guess what your code is doing.</p> <p>What do you think the effect of these lines is?</p> <pre><code> if (!(al_get_timer_count(timer) &gt; prevCount)) continue; </code></pre> <p>RUN THE LOOP! AM I READY TO RUN YET? NO? THEN RUN THE LOOP AGAIN. AM I READY TO RUN NOW? STILL NO? RUN THE LOOP AGAIN.....</p> <p>In other words, "I have the CPU now, AND I WILL NEVER SURRENDER! IF SOMEONE ELSE WANTS THE CPU THEY'LL HAVE TO TAKE IT FROM MY COLD DEAD BODY!"</p> <p>If you have nothing to <em>use the CPU for</em>, then give it up, <strong>especially</strong> if you have another thread that is ready to run.</p> <p>Use a mutex or some other synchronization primitive, or if you're ok with a more approximate time-based sleep period, call <code>Sleep()</code>.</p> <p>But don't, if you want <em>any</em> kind of decent performance, hog the CPU indefinitely, if you're waiting for another thread to do some processing.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload