What are best practices to program multithreading?
When should it be used? When shouldn't?
Simplicity:
There are rare cases where multithreading simplifies a program. This is typically when a program's purpose is inherently multi-threading, and a single-threading implementation would be unnecessarily complicated. However, such cases are rare, and usually multithreading adds a lot of complexity to an application (read: hard-to-solve bugs will occur). This basically means that as long as there is no good reason, you should not use multithreading.
Performance:
When you have a very time-consuming task, involving lots of CPU time, which is allowed to take a long time, but should not disturb more urgent tasks, such as refreshing the simulation + the screen, then the time-consuming task can be placed in a separate background thread. Besides allowing the more urgent task to have a higher refresh rate, it allows multi-core / hyperthreading systems to run both on different cores, which gives higher overall performance.
Performance can also be improved when a certain task does not involve lots of CPU operations, but potentially waits a long time on I/O operations. For instance, when doing time-consuming things on the GPU, it is possible that the rendering thread waits for the GPU to finish a certain frame. If simulation runs in a separate thread, then the simulation can be done on the CPU while rendering waits for the GPU. This way, no CPU time is wasted.
Communication:
Communication between different threads is complicated. The separation into different threads should be such that the interface between them is small and well-defined. Also, the interface should be such that the time different threads wait
for each other is reduced to a minimum. Otherwise, performance can easily be worse than in a single-threaded application. Threads should spend most of their time on doing their own job, and not on talking to each other. This means that for some kinds of tasks, a multithreading design makes no sense.