1
\$\begingroup\$

I had to write a computationally expensive routine that runs in 20-30ms. This routine cannot run in the main thread since it would kill the frame rate. The routine runs on demand, when some data change.

I wonder what would be better to use in this scenario. While I think ThreadPool will be all right, I wonder what would happen on an extreme scenario where just one core is available. Would it be better than to create a new thread every time and set the priority to below normal? I wonder though if, in this case, I would end up with the routine struggling to complete within a decent time (although waiting 1-2 seconds would be all right)

My guess is that the ThreadPool is always better in a multi-core scenario, however I wonder if in a single core scenario, creating a thread with lower priority could be a better solution (since I don't care if the computation last longer than excepted).

\$\endgroup\$
1
\$\begingroup\$

In a single thread system your lower priority thread might never run.

You could check the number of hardware threads and if there's only one you can call Thread.Sleep(x) where x is a number of milliseconds to sleep so the background thread has a chance to run.

That number could be adjusted according to the main thread's frame time to give a % of time to the background thread.

For example if the rendering took 40ms (slow system, 25fps) you could sleep the main thread for 10ms (1/4 of frame time) when the processing thread is active to control (more or less) the amount of time allocated to the background thread to roughly 20%.

(Assuming no other OS threads and apps are running at the same time.)

Or the other way around: you could have the processing thread at a higher or equal priority and sleep that one for ~8ms every ~8ms on a single-thread system but you have to check the time every so often in your processing loop.

Mixing both also helps in some situations as some OSes/kernels will keep going for 10-20ms (or more) before switching threads. For example this was useful to give the audio thread a chance but OS schedulers got a lot better. Since around 2010 I've only seen this issue on some embedded systems (Your mileage may vary).

Regarding the thread pool: For multiple short background tasks that can run in parallel many at the same time (eg: multiple AIs A* path findings in parallel or particle updates) a thread pool with job batching is the way to go on a multi-core system, but if it's 1 big job (eg: the 1 environment generator/streamer) a dedicated thread is simpler to deal with. This makes it easier to debug, inspect, profile and balance.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ low priority threads get bumped up in priority if they haven't run in a while on most OSes \$\endgroup\$ Jan 19 '16 at 9:11
  • \$\begingroup\$ thank you, nice answer. The only opinable part is about blocking the main thread, which is impossible (would make the game unresponsive), but the answer about the priority is what I was looking for \$\endgroup\$
    – sebas
    Jan 19 '16 at 10:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.