Jump to content
  • Advertisement
Sign in to follow this  
GuyWithBeard

Vsync messing with my job system

This topic is 580 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
Advertisement

You can throttle your frames or you can enable v-sync. Don't do both or you'll get drawing issues. Also, if it's causing lag then you're throttling incorrectly.

 

You really don't need to throttle the drawing in any case. Throttle your logic updates (search: "fix your timestep") but just draw as often as the machine can and just interpolate forward based on the time elapsed since the last logic update. You can enable v-sync in that case and it should work perfectly.

Share this post


Link to post
Share on other sites

Thanks for the tips, however, they don't help me in this case.

 

First of all I obviously don't have VSync and the manual frame rate limiter on at the same time, it's an either-or. In my tech there are good reasons for limiting the actual drawing rate, eg. in the level editor which is a WinForms app I am using the native engine to draw straight into a .net panel control using the raw handle and on many slightly older machines the WinForms app message pump gets flooded unless I limit the frame rate to 30 or 60.

 

I am using a fixed time step for the updates (two actually, a physics update rate and a tick rate for server gameplay and network logic). This is all fine and dandy, and besides the point I think.

 

Any idea why enabling VSync would mess up the WaitForSingleObject() duration?

Share this post


Link to post
Share on other sites
Are the jobs themselves doing anything that would have to wait for the next presentation interval?

I would try to find a thread profiler to see if you can spot anything obvious. AMD CodeXL might work, but I haven't actually used it for thread profiling yet.

Share this post


Link to post
Share on other sites

No they are running a method full of math functions, basically only updating the particle systems and not touching any other engine subsystems such as the renderer.

 

I am currently rewriting some dodgy parts of the job system (something I have put off for years already) to be able to debug it more easily. I don't particularly count on it fixing the problem though, so keep the suggestions coming!

Share this post


Link to post
Share on other sites
Have you tried to make the minimum program that behaves like that?
I mean, create only one thread, have vsync active and check if WaitForSingleObject does that weird thing.

Have you tried in another window version? Edited by nesdavid

Share this post


Link to post
Share on other sites

How do you propose having only one thread but still using WaitForSingleObject()? I am using the function explicitly for thread synchronization.

 

As for the windows version, the behavior is the same on Win7 and Win10.

Share this post


Link to post
Share on other sites
I see, sorry. Yes, I have tried with only one worker thread and it did seem like the wait duration did not vary as much as with the normal six worker thread setup.

I should have the job system refactor done later today or tomorrow and I should be able to debug it better. Cheers!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!