You are on page 1of 3

4/7/24, 4:15 PM c++ - 100% CPU utilization when using vsync (OpenGL) - Stack Overflow

100% CPU utilization when using vsync (OpenGL)


Asked 10 years, 1 month ago Modified 2 years, 1 month ago Viewed 4k times

Here is a very simple test program. When vsync is disabled this program runs at 100FPS and uses up
virtually 0% of the CPU. When I enable vsync, I get 60FPS and 25% (100% of one core on a 4 core
10 system) CPU utilization. This is using a Nvidia GPU. Searching online lead me to the suggestion to
disable "multithreaded optimization" inside of Nvidia control panel. This does decrease the CPU
utilization, but only to 10%. Furthermore, if I remove the call to sleep after SwapBuffers, I get 25%
utilization again even with multithreaded optimization disabled. Can anyone shed some light on this? Am
I doing something wrong? Is Nvidia's OpenGL implementation just hopelessly flawed?

#include <GLFW/glfw3.h>
#include <thread>
#include <cstdlib>
#include <cstdio>

int main(int argc, char *argv[])


{
if(!glfwInit())
exit(EXIT_FAILURE);

glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Vsync Test",


nullptr, nullptr);

if(!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}

glfwMakeContextCurrent(window);

#ifdef USE_VSYNC
glfwSwapInterval(1);
#else
glfwSwapInterval(0);
#endif

glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

double lastTime = glfwGetTime();


double nbFrames = 0;

while(!glfwWindowShouldClose(window))
{
double currentTime = glfwGetTime();
nbFrames++;
if (currentTime - lastTime >= 1.0)
{
char cbuffer[50];
snprintf(cbuffer, sizeof(cbuffer), "OpenGL Vsync Test [%.1f fps,
%.3f ms]", nbFrames, 1000.0 / nbFrames);
glfwSetWindowTitle(window, cbuffer);
nbFrames = 0;
lastTime++;
}
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
//limit to 100FPS for when vsync is disabled
std::chrono::milliseconds dura(10);
std::this_thread::sleep_for(dura);

https://stackoverflow.com/questions/21925313/100-cpu-utilization-when-using-vsync-opengl?rq=3 1/3
4/7/24, 4:15 PM c++ - 100% CPU utilization when using vsync (OpenGL) - Stack Overflow
}

glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}

c++ opengl driver nvidia vsync

Share Improve this question Follow asked Feb 21, 2014 at 4:30
Chris_F
5,169 5 33 68

2 Answers Sorted by: Highest score (default)

I hesitate to give this as an answer, as I don't really know the "answer," but hopefully I can shed some
light towards it.
8
I have an nVidia GPU as well and I've noticed the same thing. My guess is that the driver is essentially
spin-waiting:

while(NotTimeToSwapYet()){}

(or whatever the fancy driver version of that looks like).

Using process hacker to sample some stack traces from nvoglv32.dll 's thread, The thing that's at the
top of the list about 99% of the time is

KeAcquireSpinLockAtDpcLevel()

which is usually downstream from things like

KiCheckForKernelApcDelivery() and EngUnlockDirectDrawSurface()

I'm not well versed enough in Windows driver programming to call this conclusive, but it certainly doesn't
tell me I'm wrong either.

And it doesn't look like you're doing anything obviously wrong either. It's been my experience that swap
timing in non-exclusive Windows applications is just really painful: there's a lot of trial and error involved,
and a lot of variability between different systems. As far as I know there is no "right" way to do it that will
work well all the time (please, someone tell me I'm wrong!).

In the past, I've been able to rely on vsync to keep CPU usage low (even if it did make things a bit less
responsive), but that doesn't seem to be the case any longer. I switched from DirectX to OpenGL
relatively recently, so I couldn't tell you if this is a recent change in nVidia's driver, or whether they just
treat DX and OpenGL differently with respect to vsync.

Share Improve this answer Follow answered Feb 21, 2014 at 8:23
Profram Files
376 2 6

https://stackoverflow.com/questions/21925313/100-cpu-utilization-when-using-vsync-opengl?rq=3 2/3
4/7/24, 4:15 PM c++ - 100% CPU utilization when using vsync (OpenGL) - Stack Overflow

1 Not quite definitive, but definitely helpful. I did find this post (forum.openscenegraph.org/viewtopic.php?
t=3653#18283) where someone got some feedback from the driver developers. According to their response, the
driver yields. To test this for myself I loaded up my 3D rendering suite of choice and proceeded to max out all four
of my CPU cores while I had the OpenGL program running. Its CPU utilization went from 25% to 0%. It seems
while it maxes out a core, it doesn't actually hog it. – Chris_F Feb 24, 2014 at 5:22

@Chis_F Thanks, that's good to know (and somewhat encouraging). But my main concern with the high CPU
usage is that it discourages laptops from entering low power mode; I'm not sure if the usage being "artificial" makes
a difference there. Maybe mobile drivers are set up differently -- I don't have one to test. – Profram Files Feb 24,
2014 at 9:00

That's certainly a concern. Yielding would make no difference as far as power consumption goes, but maybe the
drivers for their mobile GPUs operate differently. – Chris_F Feb 24, 2014 at 19:45

I've noticed that Blender uses almost no CPU when idle, even if I force vsync on. As far as I know it uses OpenGL.
I wonder what they are doing differently to manage that. – Chris_F Feb 25, 2014 at 3:08

Blender seem to be rendering frames only when something have change. I tested it with Fraps. I do something
similar when it's possible and it solve the problem. It's fine in 3d editor, but it's not an option when you are making
game or demo. I'm using winpai and if I use GetMessage instead of PeekMessage then application will wait for
user input before every frame. So frames are rendered only when user move mose, or something. – LovelyHanibal
Jul 5, 2020 at 15:21

after swap buffers, call DwmFlush(); and it will no longer use 100% cpu!

2 Share Improve this answer Follow answered Feb 14, 2022 at 9:14
Farzher
14.3k 21 71 103

https://stackoverflow.com/questions/21925313/100-cpu-utilization-when-using-vsync-opengl?rq=3 3/3

You might also like