Multi-threaded Rendering and Physics Simulation

by Rajshree Chabukswar, Adam T. Lake, and Mary R. Lee, Intel® Software Solutions Group


Introduction

Learn how to decouple rendering and physical simulation in a multi-threaded environment with a simple physical simulation demonstration. The sample code provided with this paper can either be used as an example or adapted directly into your game engine.

This paper demonstrates bouncing spheres within a cube with sphere-sphere and sphere-plane collision detection mechanisms implemented using Newtonian physics. Initially, spheres collide with each other and the walls of the enclosing cube. After collision is detected, collision response code is executed to calculate the new velocity. The user has an option to run either a multi-threaded or single threaded version. Threading is implemented to compute physics equations in a separate thread while rendering takes place in the main thread.

The goal is to showcase how to use separate threads to perform CPU intensive physics computations independent of the actual rendering process. It is beneficial to use multiple threads to perform different tasks since future processor architectures are moving towards multiple cores. Hence, the performance of an application can be increased by having multiple threads work individually to take advantage of available CPU cycles. The paper first discusses the basics of this implementation followed by the physics concepts used in our demo. Future work and reference section is also included.


Download Source Code

View entire article (PDF 432KB)

 

For more complete information about compiler optimizations, see our Optimization Notice.

5 comments

Top
Hank E. P.'s picture

I have to echo what anonymous said. I was skeptical about their comment at first, but after reading through the article and looking at the code I see they were not incorrect.

This is a very poor demonstration of this technique, and I do not recommend using the source code here as a basis for anything. While the concept was well-meaning, the implementation negates all benefits of using separate simulation and rendering threads.

In this implementation, in "multi-threaded" mode, the simulation thread runs, computes the results, pauses, then the render thread draws, completes, pauses, then back to the simulation. It does not illustrate anything. The graph showing that single-threaded ran at 100% CPU while multi-threaded ran at 15%/85% illustrated nothing more than the fact that 15 + 85 = 100.

Even taking a step back just to look at the general techniques here, there is still no merit. The simulation thread uses the same copy of the data that the rendering thread uses, so even if you wanted to try and run the two threads in parallel, you could not, as both threads could not safely access the data at the same time. 

The only redeeming quality about this article is that it briefly mentions that more complex physics simulations could be split to multiple simulation threads. However, this is unrelated to separating simulation and rendering, isn't really the topic of the article, and isn't actually illustrated anyways.

Do not use the techniques presented here. You will gain nothing except an overcomplication of your code, and a bunch of context switching overhead for no reason. The true goal for separating simulation and rendering, which this article does not illustrate, is to have the renderer be rendering the previous frame at the same time the simulation is computing the current frame. That isn't accomplished here. The real way to accomplish that is to have the simulation thread do all the math, then copy a snapshot of the relevant data for rendering (e.g. object positions) to a safe place for the rendering thread, then go on to compute the next frame while the renderer draws the snapshot data. (The Unreal Engine threaded rendering article touches on this topic much more accurately: https://docs.unrealengine.com/latest/INT/Programming/Rendering/ThreadedRendering/)

There are other coding red flags here too; for example the comment about "TODO: Check if resources are NULL before deleting them." While that's needed for the COM stuff it is well-known and documented that both free() and delete are no-ops on NULL, and the check is not necessary (nor is the reset in the destructor). While this is totally not a problem to do, it does seem to be one of a few indications that the authors of this article, while well-meaning, did not have the experience necessary to write this article at the time that they wrote it.

anonymous's picture

What is the purpose of this design? First of all, the system runs in lockstep with just 1 other thread, so there is no benefit of having another thread. I would only see the benefit in having multiple threads (scaled based on the quantity of cores) to simulate physics, and then return to rendering. There is no point in having 1 extra thread jump in, pause the previous thread, do its' thing and resume the initial thread. Absolutely pointless, Intel - this article was written by an intern, I presume?

At least could have made it useful from the start by using a thread pool, as it stands this is a pointless example of threading - no benefit!

Otherwise, add something interesting - like another thread that does something which would alter sphere's velocity/position, like a "Wind" thread (parallel to physics and rendering sim with direct interference). This way you could demonstrate at least some decoupling or synchronization technique (avoiding using a mutex).

Aubrey W.'s picture

The source code link has been corrected. Thank you for bringing this to our attention.

anonymous's picture

I want to download the source code for this article "Multi-threaded Rendering and Physics Simulation", but the source code link is wrong. Could you send me the source code directly through my emial? Or can you fix the wrong link?

Add a Comment

Have a technical question? Visit our forums. Have site or software product issues? Contact support.