PeekMessage()需要1-2毫秒来检索WM_MOUSEMOVE消息?

我在这里看过很多关于PeekMessage和WM_MOUSEMOVE的post,但到目前为止我还没有发现任何与性能有关的东西。

长话短说; 我正在做PC游戏开发,昨天我注意到,只要快速移动鼠标,我就可以将我们的应用程序从稳定的500+ FPS(在菜单中)带到一位数的FPS(低至6)。

经过几个小时的挖掘和分析,我发现源是PeekMessage()。 不是DispatchMessage()的消息,只是偷看。 我非常频繁地(每帧多次)测量调用这个函数,时钟频率在1-2 ms。 如果将鼠标移动速度与快速移动相结合,抽取消息队列可能会使我的渲染帧数高达1000-2000毫秒。 听起来很可笑,但我实际上从MS下载了一个超级基本的DirectX示例,并在那里testing了相同的结果。

整个示例太大,无法粘贴,但是如果您想尝试,请下载示例: http : //code.msdn.microsoft.com/Direct3D-Tutorial-Win32-829979ef

并做出如下修改;

typedef unsigned __int64 QWORD; // 64-bit unsigned. DOUBLE GSecondsPerCycle; void appInitTiming(void) { LARGE_INTEGER Frequency; QueryPerformanceFrequency(&Frequency); GSecondsPerCycle = 1.0 / Frequency.QuadPart; } QWORD appCycles() { LARGE_INTEGER Cycles; QueryPerformanceCounter(&Cycles); return Cycles.QuadPart; } int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow ) { UNREFERENCED_PARAMETER( hPrevInstance ); UNREFERENCED_PARAMETER( lpCmdLine ); if( FAILED( InitWindow( hInstance, nCmdShow ) ) ) return 0; if( FAILED( InitDevice() ) ) { CleanupDevice(); return 0; } appInitTiming(); // Main message loop MSG msg = {0}; while( WM_QUIT != msg.message ) { QWORD StartCycles = appCycles(); BOOL hasMsg = PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ); const QWORD DeltaCycles = appCycles() - StartCycles; double deltaMS = DeltaCycles * GSecondsPerCycle * 1000.0; if (deltaMS > 1/* || msg.message == 512*/) { std::ostringstream os; os << "SlowPeekMsg ID: " << msg.message << ", time: " << deltaMS << "ms" << std::endl; std::string buffer(os.str()); OutputDebugStringA(buffer.c_str()); } if(hasMsg) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(); } } CleanupDevice(); return ( int )msg.wParam; } 

给这个去吧:

 UNREFERENCED_PARAMETER( hPrevInstance ); UNREFERENCED_PARAMETER( lpCmdLine ); if( FAILED( InitWindow( hInstance, nCmdShow ) ) ) return 0; if( FAILED( InitDevice() ) ) { CleanupDevice(); return 0; } appInitTiming(); // Main message loop MSG msg = {0}; while( WM_QUIT != msg.message ) { QWORD StartCycles = appCycles(); while(PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE )) { TranslateMessage(&msg); DispatchMessage(&msg); } const QWORD DeltaCycles = appCycles() - StartCycles; double deltaMS = DeltaCycles * GSecondsPerCycle * 1000.0; if (deltaMS > 1/* || msg.message == 512*/) { std::ostringstream os; os << "SlowPeekMsg ID: " << msg.message << ", time: " << deltaMS << "ms" << std::endl; std::string buffer(os.str()); OutputDebugStringA(buffer.c_str()); } Render(); } CleanupDevice(); return ( int )msg.wParam; 

这可能只是像上面提到的一个评论者那样的怪异的东西。