为什么当我的应用程序最小化时CPU使用率会增加

Why does CPU usage increase when my application is minimized?

本文关键字:CPU 使用率 增加 最小化 我的 应用程序 为什么      更新时间:2023-10-16

我正在编程一个计算器。当窗口最大化时,CPU使用率约为12%,但当窗口最小化时,CPU的使用率上升到约50%。为什么会发生这种情况,我该如何预防?这是我认为导致问题的一段代码。

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_ACTIVATE:
    if(!HIWORD(wParam))
        active = true;
    else
        active = false;
    return 0;
case WM_SYSCOMMAND:
    switch(wParam)
    {
    case SC_SCREENSAVE:
    case SC_MONITORPOWER:
        return 0;
    }
    break;
case WM_CLOSE:
    PostQuitMessage(0);
    return 0;
case WM_KEYDOWN:
    if( (wParam >= VK_LEFT && wParam <= VK_DOWN) || wParam == VK_CONTROL)
        myCalc.handleInput(wParam, true);
    return 0;
case WM_CHAR:
    myCalc.handleInput(wParam);
    return 0;
case WM_SIZE:
    ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));  //LOWORD = Width; HIWORD = Height
    return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int     nShowCmd)
{
MSG msg;
if(!CreateGLWindow(WINDOW_CAPTION, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP))
{
    return 0;
}
while(!done)    //Main loop
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if(msg.message == WM_QUIT)
            done = true;
        else
        {
            TranslateMessage(&msg); //Translate the message
            DispatchMessage(&msg);  //Dispatch the message
        }
    }
    else
    {
        //Start the time handler
        myTimeHandler.Start();
        //Draw the GL Scene
        if(active)
        {
            DrawGLScene();      //Draw the scene
            SwapBuffers(hDC);   //Swap buffer (double buffering)
        }
        //Regulate the fps
        myTimeHandler.RegulateFps();
    }
}
//Shutdown
KillGLWindow();
return(msg.wParam);
}

我的猜测是,如果active为false,那么主循环运行时不会有任何延迟。线程在该循环中无限旋转,并使两个处理器核心中的一个保持繁忙(这就是为什么您看到50%的CPU负载)。

如果active为true,则交换操作将等待下一次vsync,并将循环延迟到下一次屏幕刷新,从而降低CPU负载。(线程在窗口函数内等待事件发生的时间不计入其CPU负载。)

为了解决这个问题,您可以在不想呈现任何内容的时间切换到基于GetMessage的消息循环。

OpenGL窗口覆盖的区域越小,绘制场景的速度就越快(关键术语是填充率),因此事件循环的迭代频率就越高。我看到你有一些函数RegulateFps——对我来说,这听起来像是一个繁忙的循环,直到渲染器中消耗了一定的时间。也就是说,你真的在浪费CPU时间来获得……啊,你为什么一开始就想保持低帧速率?把它扔掉。

当然,如果你最小化它,你可以设置active = false,这样就根本不做GL的事情,但仍然在繁忙的循环中浪费时间。

尝试在驱动程序选项中打开V同步,并使用双缓冲,然后wglSwapBuffers将阻塞直到垂直空白。如果active==false不是PeekMessage而是GetMessage

好的。我看到了你的一个逻辑流程。


while(!done)    //Main loop
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
       ......
    }
    else
    {
       .... rendering.
    }
}

最小化时,peekMessage将始终失败,因此u将进入渲染部分。

这导致u使用100%的单核cpu,因为它处于while循环中,从不休眠、等待,只是一遍又一遍地画画。

您可能需要设置渲染帧的最短时间。

我的建议是:


// set a timer for wakeup ur process.
while (::GetMessage(&msg, NULL, 0, 0))
{
  // handle the messages
  // do check the rendering to see if you need to render.
  if (currentTime - lastDrawTime > MINIMIUM_RENDER_INTERVAL)
      // rendering.
}