我正在尝试制作一个Gameboy模拟器,但它的运行速度比预期的要快。
这是我在主循环中使用的时间代码。
if (cpu.T >= CLOCKSPEED / 40) // if more than 1/40th of cycles passed
{
// Get milliseconds passed
QueryPerformanceCounter(&EndCounter);
unsigned long long counter = EndCounter.QuadPart - LastCounter.QuadPart;
MSperFrame = 1000.0f * ((double)counter / (double)PerfCountFrequency);
LastCounter = EndCounter;
// if 1/40th of a second hasn't passed, wait until it passes
if (MSperFrame < 25)
Sleep(25 - MSperFrame);
MSperFrame = 0;
cpu.T -= CLOCKSPEED / 40;
}
CLOCKSPEED
是Gameboy CPU每秒的周期数(4194304)。cpu.T
是到目前为止经过的周期数。PerfCountFrequency
是在进入循环之前调用的QueryPerformanceFrequency的结果。
当我将其与另一个以正确速度运行的模拟器(VBA)进行比较时,我的模拟器运行得更快。问题出在哪里?
QueryPerformancCounter()
。我听说现代CPU为了节省电力而动态地改变它们的速度,这并不总是准确的,尽管我没有确定的来源。现在我通常使用 std::chrono::steady_clock 进行分析,只要它的粒度足够小,比你想计时的周期小即可。 - RyanP