Windows游戏循环双核50%CPU

cpx*_*cpx 4 winapi message-queue game-loop

仅游戏循环使用50%的CPU使用率,我还没有完成任何渲染工作.我在这做什么?

        while(true)
        {
            if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
            {
                    if(msg.message == WM_QUIT || 
                           msg.message == WM_CLOSE || 
                           msg.message == WM_DESTROY)
                            break;

                    TranslateMessage(&msg);
                    DispatchMessage(&msg);                   
            }
            else
            {
                    //Run game code, break out of loop when the game is over

            }
        }
Run Code Online (Sandbox Code Playgroud)

tva*_*son 8

经典忙/等待循环.您的CPU忙于检查(并无限制地重新检查)消息.您需要以阻止方式等待消息,或者更有可能使用定期唤醒游戏线程的计时器,以便它可以完成其工作.然后游戏线程会消失,直到下次它被唤醒.

  • 不,它不需要尽可能快地渲染.渲染速度比屏幕刷新速度快,毫无意义.理想的是 - 总是 - 以能够阻止用于至少下一个屏幕间隔 - 大多数图形框架(OpenGL的/ DirectX的)仅允许显示间隔运行独家/全屏应用程序时synching.下一个选项是选择一个"足够好"的计时器 - 通常是为了实现> 30fps的帧速率,但实际上并不比100fps快.因此通常使用10到33ms的定时器. (3认同)
  • 对于具有正常渲染循环的高性能游戏,计时器不是正确的方法,它需要尽可能快地渲染并且对于CPU周期而言是贪婪的. (2认同)
  • 当你的显示器刷新率为60Hz时,400fps除了证明你的ePeen的大小之外做了什么呢? (2认同)

kma*_*rsh 5

您已创建忙等待循环.您可能正在使用100%的一个核心,因此50%的双核心.

您需要找到一种方法来阻止读取(在单独的线程中),根据需要阻止和退出I/O调用,或者在线程中执行其他有用的操作.每种策略都有其优点和缺点.单独的线程需要同步的通信方法,如互斥锁.掉出I/O意味着当没有消息时,此线程中没有其他任何有用的东西.在循环中执行其他操作可能会导致块状处理("其他内容"会在较少的消息上处理,而在更多消息上会更少处理).