Hey guys,
I have been investigating a weird slowdown in my project that turned out to be Vsync causing my job system to perform poorly. I am not sure why this is happening though, so I ask for ideas.
I have a simulation running where particle systems are updated on the job system. The job system is fairly standard, it uses a pool of threads and gives those threads jobs to do. In addition, you can add dependencies to a job and have the main thread wait until the job is complete. In the case with the particle systems causing problems, each particle system's update function is thrown on the job system and the main thread waits for all of the update jobs to complete before continuing. In practice this is implemented with Win32 events and the main thread is using WaitForSingleObject() to wait for the depencency linked to all the update jobs.
This works fine when the frame rate is unlocked, and it even works fine when the main thread is limiting the framerate through code (by spinning in the beginning of the frame until the desired delta time has been reached). However, when turning on VScync to limit the framerate (in this case to 60FPS) the WaitForSingleObject() call starts taking anywhere between 1ms-500ms. With VSync off I can happily throw hundreds of particle systems on the job system and it performs fine. With VSync on the multithreaded update of particle systems causes the framerate to vary wildly (as previously mentioned). However, if I update the particle systems serially on the main thread the system works farily ok (although a bit slower since it does not benefit from the job system) even with VSync on.
So in short, having Vsync on makes the job system dependency waiting perform very poorly. Any idea what might cause this? Literally the only different in my engine between having VSync on/off is passing 1 or 0 as the first parameter to IDXGISwapChain::Present(). I am using DX11 for rendering and the swap effect has been set to DXGI_SWAP_EFFECT_DISCARD. The tests have been done in window mode. With VSync on I presume the call to Present() sleeps until it is time to present the content on screen. Is it possible that the machine does some weird context switching because of this, causing my threads to jump around and cause this behavior?
Thanks!