我在这里查看了许多有关PeekMessage和WM_MOUSEMOVE的帖子,但是到目前为止,我还没有发现任何与性能相关的信息。
长话短说;我正在做PC游戏开发,昨天我注意到,仅通过快速移动鼠标,我就可以将我们的应用程序从稳定的500+ FPS(在菜单中)提高到个位数FPS(低至6)。
经过几个小时的挖掘和分析,我发现源是PeekMessage()。该消息不是DispatchMessage(),而是偷看。我测量了单独调用该函数的频率为1-2 ms(每帧多次)。如果将其与快速的鼠标移动相结合,则泵送消息队列可能会使我每帧渲染花费1000-2000ms以上。听起来很荒谬,但是我实际上从MS下载了一个 super 基本的DirectX示例,并在那里测试了相同的东西,并获得了相同的结果。
整个样本太大,无法在此处粘贴,但是如果您想尝试,请在以下位置下载样本:
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;
可能只是像上面提到的评论者之类的东西而已。