Quote: "Even VSYNC is sort of a hack that wastes CPU cycles"
No it does not if you run in dedicated "Set Window off" mode and use Set Display mode to set the VSync.
Quote: "but whatever method you use, it is better to limit the program to the monitor refresh rate"
Also wrong, if you run VSync=ON in
windowed mode it will run significantly slower than any other display mode with the same workload (Edit) when it reaches the VSync threshold (Edit).
Test this code.
It will first calculate the workload for running full out unsynced.
Then it will enter normal run mode. You should see it run at the set TargetFPS.
You can now press Space to change the "Set Display Mode" to running VSync=ON in windowed mode, see the difference?
Subsequent Space presses shows the VSync=OFF in both dedicated and non dedicated windowed mode. These display modes runs at the set TargetFPS as the first test did. Also note the VSYNC=ON in dedicated mode runs exactly as fast as it does nonsynced full out so there is no loss in running VSync=ON in window off mode.
Decrease the TargetFPS variable and the framerate loss is even more noticeable.
// Duke E 100615
// Tests all Display Modes.
// The purpuse of this test is to show that window mode with VSync = ON runs slow.
// Also shows that VSync=ON in dedicated mode is as fast as running full out unsynced.
Global OldFrame as Double Integer
Global Elapsed as float
Global Duration as float
Global PerfFrq as Double Integer
Global FPS as float
Global TestValue as integer
Global TargetFPS as Integer = 60
Sync On
set display mode DESKTOP WIDTH(),DESKTOP Height(),32,0
SET WINDOW LAYOUT 0, 0, 1
set window position 0,0
RemakeBox()
InitQueryPerformanceFrequency()
FindSixtyFPS=1
Do
GetElapsed()
if FindSixtyFPS=1
inc TestValue,10
DoWork()
endif
if Screen Fps()<=TargetFPS and Screen Fps()<>0.0 and StartTests=0
FindSixtyFPS=0
StartTests=1
endif
if StartTests
if StartTests = 1 and Spacekey() and Delay<Timer()
Delay=Timer()+1000
StartTests = 2
set display mode DESKTOP WIDTH(),DESKTOP Height(),32,1
SET WINDOW LAYOUT 0, 0, 1
Sync
RemakeBox()
endif
if StartTests = 2 and Spacekey() and Delay<Timer()
Delay=Timer()+1000
StartTests = 3
set display mode DESKTOP WIDTH(),DESKTOP Height(),32,0
set window position 0,0
Set Window Off
Sync
RemakeBox()
endif
if StartTests = 3 and Spacekey() and Delay<Timer()
Delay=Timer()+1000
StartTests = 4
set display mode DESKTOP WIDTH(),DESKTOP Height(),32,1
set window position 0,0
Set Window Off
Sync
RemakeBox()
endif
DoWork()
ENDIF
Speed#=0.11
if StartTests = 0
Text 1,0, " Calculating workload for unsynced " + str$(TargetFPS) + "FPS (set display mode DESKTOP WIDTH(),DESKTOP Height(),32,0)"
Text 1,30, "Please wait until FPS reaches TargetFPS (" + str$(TargetFPS) + ") ..."
ENDIF
if StartTests = 1
Text 1,0, " Running unsynced " + str$(TargetFPS) + "FPS (set display mode DESKTOP WIDTH(),DESKTOP Height(),32,0)"
Text 1,30, "Press space to change display for VSync mode..."
Addinfo$ = " < -- keeps "+ str$(TargetFPS) + " FPS"
endif
if StartTests = 2
Text 1,0, " Running VSync=ON with the _same_ workload as unsynced " + str$(TargetFPS) + " FPS (set display mode DESKTOP WIDTH(),DESKTOP Height(),32,1)"
Text 1,30, "Press space to change display for VSync mode Dedicated unsynced..."
Addinfo$ = " < -- Significantly lower in windowed VSync mode (Decrease TargetFPS and it gets even worse)"
ENDIF
if StartTests = 3
Text 1,0, " Running unsynced in dedicated (Window off) mode " + str$(TargetFPS) + " FPS (set display mode DESKTOP WIDTH(),DESKTOP Height(),32,0)"
Text 1,30, "Press space to change display for VSync mode Dedicated VSync..."
Addinfo$ = " < -- keeps "+ str$(TargetFPS) + "FPS"
ENDIF
if StartTests = 4
Text 1,0, " Running VSync=ON in dedicated (Window off) mode " + str$(TargetFPS) + " FPS (set display mode DESKTOP WIDTH(),DESKTOP Height(),32,1)"
Addinfo$ = " < -- keeps "+ str$(TargetFPS) + "FPS (this shows it is as fast as running unsynced with the same workload)"
ENDIF
Text 1,60, "Screen FPS() : " + str$(Screen Fps()) + Addinfo$
Text 1,80, "Calculated FPS: " + str$(FPS)
Text 1,100, "Frame Elapsed : " + str$(Elapsed)
inc Angle#, Speed#*Elapsed
if Angle#>360.0 then Angle# = 0.0
Xrotate Object 1,WrapValue(Angle#)
sync
LOOP
Function GetElapsed()
// Perftimer, have to call InitQueryPerformanceFrequency() first to get the hosting hardwares performance frequency.
local FrameTime as Double Integer
local Delta as Double Integer
FrameTime = perftimer()
Delta = FrameTime - OldFrame
OldFrame = FrameTime
FPS = PerfFrq/Delta
Elapsed = 1000.0/FPS
ENDFUNCTION
Function InitQueryPerformanceFrequency()
local Ptr as Dword
Load DLL "kernel32.dll", 1
Ptr = Make Memory(8)
Null = Call Dll(1, "QueryPerformanceFrequency", Ptr )
PerfFrq =(*Ptr)
Delete DLL 1
DELETE MEMORY Ptr
ENDFUNCTION
Function RemakeBox()
Make Object Box 1,10,10,5
ENDFUNCTION
Function DoWork()
for i = 0 to TestValue
a#=sqrt(i)
a# = a#^a#/1000.0
NEXT
ENDFUNCTION
What causes this frame rate drop in VSync=ON window mode?
Have irritated me a while now.
Regards