Sponsors: KDAB and Whole Tomato Software

20 March 2012

FPS limit

coding icon
For some time I've tried to investigate why my OpenGL applications use almost 100% of CPU. The apps usually were quite simple, but still, CPU was heavily loaded. As it appears, the reason was quite simple: I had a window message loop (in WinApi) which was not perfectly implemented.

So, how to lower the CPU consumption rate?

The original message loop:
while (true)
{
    PeekMsg(...)
    if (quit....) break;
    if (msg)
        handle message;
    else
    {
        Render();
        SwapBuffers()
    }
} 
Whenever there was no window message I rendered the scene. In that way you have max frame rate - full speed of a game, but also 100% of cpu usage.

Solution Ideas

One of the first idea is to limit FPS by using VSync (Vertical synchronization) (via wglSwapIntervalEXT).
if (is_supported_extension_WGL_EXT_swap_control) {
    wglSwapIntervalEXT(1);
}
I got 60 HZ limit, but still my application used 100% CPU... The reason: driver waits for vsync and does not return to main thread (or allows other threads to run).
Finally I got some clever solution: WaitableTimers. The whole idea came from: www.codeguru.com/forum/archive
while (true) 
{ 
    SetWaitableTimer(myTimer, desired_frame_duration, ...); 
    PeekMsg(...) 
    if (quit....) break; 
    if (msg)
        handle message; 
    else 
    { 
        Render(); 
        SwapBuffers();
    }
    WaitForSingleObject(myTimer); 
} 
In that way we limit loop to run at desired frame rate. It is working, and now I got around 15% CPU usage at 50 fps. I need to investigate that solution a bit more, but it is quite promising :)
todo: add final code here...
Other idea: use OpenGL queries to query something - meaning rendering is finished or vsync. It can work even better than those timers but implementation may be a bit complicated.

Links

Interested in new blog posts and bonus content? Sign up for my newsletter.

© 2017, Bartlomiej Filipek, Blogger platform
Any opinions expressed herein are in no way representative of those of my employers.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.