I am working on day 19 and trying to improve the accuracy of sleep to reach 30 FPS. Casey seems to be able to hit 33.3 ms consistently.
I setup a minimal repro program, but my results are still much more imprecise:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | [5/15/2020 7:51:29 AM] Debugging new process...[OK] Process ID: 10592 Milliseconds per Frame: 33.884300ms/f, work seconds: 0.000000s, sleep 0.033333s, sum 0.033333s Milliseconds per Frame: 34.062199ms/f, work seconds: 0.000228s, sleep 0.033105s, sum 0.033333s Milliseconds per Frame: 33.339798ms/f, work seconds: 0.000114s, sleep 0.033219s, sum 0.033333s Milliseconds per Frame: 34.079201ms/f, work seconds: 0.000146s, sleep 0.033187s, sum 0.033333s Milliseconds per Frame: 34.028900ms/f, work seconds: 0.000311s, sleep 0.033022s, sum 0.033333s Milliseconds per Frame: 33.819199ms/f, work seconds: 0.000255s, sleep 0.033078s, sum 0.033333s Milliseconds per Frame: 34.026203ms/f, work seconds: 0.000257s, sleep 0.033076s, sum 0.033333s Milliseconds per Frame: 33.703201ms/f, work seconds: 0.000215s, sleep 0.033118s, sum 0.033333s Milliseconds per Frame: 33.581997ms/f, work seconds: 0.000229s, sleep 0.033104s, sum 0.033333s Milliseconds per Frame: 33.659000ms/f, work seconds: 0.000214s, sleep 0.033120s, sum 0.033333s Milliseconds per Frame: 33.435600ms/f, work seconds: 0.000237s, sleep 0.033096s, sum 0.033333s Milliseconds per Frame: 33.768799ms/f, work seconds: 0.000220s, sleep 0.033114s, sum 0.033333s Milliseconds per Frame: 33.410198ms/f, work seconds: 0.000095s, sleep 0.033238s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000071s, sleep 0.033262s, sum 0.033333s Milliseconds per Frame: 33.650002ms/f, work seconds: 0.000155s, sleep 0.033179s, sum 0.033333s Milliseconds per Frame: 33.786400ms/f, work seconds: 0.000078s, sleep 0.033255s, sum 0.033333s Milliseconds per Frame: 33.975998ms/f, work seconds: 0.000143s, sleep 0.033190s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000057s, sleep 0.033276s, sum 0.033333s Milliseconds per Frame: 33.571800ms/f, work seconds: 0.000110s, sleep 0.033224s, sum 0.033333s Milliseconds per Frame: 34.081802ms/f, work seconds: 0.000114s, sleep 0.033219s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000185s, sleep 0.033148s, sum 0.033333s Milliseconds per Frame: 33.910301ms/f, work seconds: 0.000294s, sleep 0.033039s, sum 0.033333s Milliseconds per Frame: 33.775898ms/f, work seconds: 0.000171s, sleep 0.033162s, sum 0.033333s Milliseconds per Frame: 33.340000ms/f, work seconds: 0.000388s, sleep 0.032946s, sum 0.033333s Milliseconds per Frame: 33.353100ms/f, work seconds: 0.000242s, sleep 0.033092s, sum 0.033333s Milliseconds per Frame: 33.387798ms/f, work seconds: 0.000225s, sleep 0.033108s, sum 0.033333s Milliseconds per Frame: 33.971600ms/f, work seconds: 0.000137s, sleep 0.033196s, sum 0.033333s Milliseconds per Frame: 34.082600ms/f, work seconds: 0.000138s, sleep 0.033196s, sum 0.033333s Milliseconds per Frame: 33.896500ms/f, work seconds: 0.000139s, sleep 0.033194s, sum 0.033333s Milliseconds per Frame: 34.114902ms/f, work seconds: 0.000132s, sleep 0.033201s, sum 0.033333s Milliseconds per Frame: 33.951202ms/f, work seconds: 0.000186s, sleep 0.033147s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000362s, sleep 0.032971s, sum 0.033333s Milliseconds per Frame: 33.848999ms/f, work seconds: 0.000261s, sleep 0.033072s, sum 0.033333s Milliseconds per Frame: 33.383999ms/f, work seconds: 0.000091s, sleep 0.033242s, sum 0.033333s Milliseconds per Frame: 33.477200ms/f, work seconds: 0.000244s, sleep 0.033089s, sum 0.033333s Milliseconds per Frame: 33.819798ms/f, work seconds: 0.000188s, sleep 0.033146s, sum 0.033333s Milliseconds per Frame: 34.158901ms/f, work seconds: 0.000158s, sleep 0.033175s, sum 0.033333s Milliseconds per Frame: 33.386902ms/f, work seconds: 0.000183s, sleep 0.033150s, sum 0.033333s Milliseconds per Frame: 33.463398ms/f, work seconds: 0.000180s, sleep 0.033154s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000198s, sleep 0.033135s, sum 0.033333s Milliseconds per Frame: 33.338497ms/f, work seconds: 0.000185s, sleep 0.033148s, sum 0.033333s Milliseconds per Frame: 33.333397ms/f, work seconds: 0.000370s, sleep 0.032963s, sum 0.033333s [5/15/2020 7:51:31 AM] Process exited with exit code 3221225786 |
Do you see any obvious issue?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #include <stdint.h> #include <windows.h> #include <stdio.h> typedef uint32_t bool32; typedef float real32; static int64_t GlobalPerfCountFrequency; inline real32 Win32GetSecondsElapsed(LARGE_INTEGER Start, LARGE_INTEGER End) { return ((real32)(End.QuadPart - Start.QuadPart) / (real32)GlobalPerfCountFrequency); } inline LARGE_INTEGER Win32GetWallClock(void) { LARGE_INTEGER EndCounter; QueryPerformanceCounter(&EndCounter); return EndCounter; } int main() { LARGE_INTEGER PerfCountFrequencyResult; QueryPerformanceFrequency(&PerfCountFrequencyResult); GlobalPerfCountFrequency = PerfCountFrequencyResult.QuadPart; UINT DesiredSchedulerMS = 1; bool32 SleepIsGranular = (timeBeginPeriod(DesiredSchedulerMS) == TIMERR_NOERROR); #define MonitorRefreshHz 60 #define GameUpdateHz (MonitorRefreshHz/2) real32 TargetSecondsPerFrame = 1.0f / (real32)GameUpdateHz; LARGE_INTEGER LastCounter = Win32GetWallClock(); while (1) { LARGE_INTEGER WorkCounter = Win32GetWallClock(); real32 WorkSecondsElapsed = Win32GetSecondsElapsed(LastCounter, WorkCounter); real32 SecondsElapsedForFrame = WorkSecondsElapsed; real32 SleepSeconds = 0; if(SecondsElapsedForFrame < TargetSecondsPerFrame) { if(SleepIsGranular) { SleepSeconds = (TargetSecondsPerFrame - SecondsElapsedForFrame); if(SleepSeconds > 0) { Sleep((DWORD)(1000.0f * SleepSeconds)); } } else { *(int*)0 = 0; } while(SecondsElapsedForFrame < TargetSecondsPerFrame) { SecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock()); } } else { // Missed framerate } LARGE_INTEGER EndCounter = Win32GetWallClock(); real32 MSPerFrame = 1000.0f * Win32GetSecondsElapsed(LastCounter, EndCounter); LastCounter = EndCounter; char DebugBuffer[256]; _snprintf_s(DebugBuffer, sizeof(DebugBuffer), "Milliseconds per Frame: %fms/f, work seconds: %fs, sleep %fs, sum %fs\n", MSPerFrame, WorkSecondsElapsed, SleepSeconds, WorkSecondsElapsed + SleepSeconds); OutputDebugString(DebugBuffer); } return(0); } |
Here is the build command:
1 2 3 4 | set CommonCompilerFlags=-MT -nologo -Gm- -GR- -EHa- -Oi -WX -W4 -wd4201 -wd4100 -wd4189 -FC -Z7 /INCREMENTAL:NO /DEBUG:FULL set CommonLinkerFlags=-opt:ref user32.lib Winmm.lib cl %CommonCompilerFlags% main.cpp /link %CommonLinkerFlags% |