-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix CPU usage when using vsync #90
base: main
Are you sure you want to change the base?
Conversation
I noticed that the CPU usage increases over time when using `setVSync(true)`, which is the default. This happens even for a simple example like `lines.nim`. When using `setVSync(false)`, this does not happen, but of course this has the drawback of tearing or not smooth screen updates. The main difference when using `setVSync(false)` is in `proc run*()` where waiting is done manually using `delay()`. However, it seems that when solely relying on vsync, CPU usage seems to increase over time. As a solution this pull request adds a delay(1) even for the vsync case, if `sleepTime` is not smaller than 1.0 ms. This fixes the reported CPU usage problem.
Are you seeing this behaviour on Linux? We've seen similar before on Linux where vsync doesn't appear to be supported correctly. |
No, I'm using Windows 10 on an Intel HD Graphics 2000. The fan of my Notebook makes high CPU usage very noticable :) |
Perhaps we can do something to determine if vsync is working correctly or not, if the time between loops is super short (and not close to vsync frequency), we could disable vsync mode and use the wait timer instead |
Hmm, I would not prefer having the wait timer approach being automatically turned on, as it has the mentioned drawbacks on its own. The proposed kludge fixes the vsync CPU issue for me, and I can enjoy smooth scrolling. If it does not gets mainlined, I can live with it too :) |
If you're getting high CPU usage with vsync mode it's likely vsync is not working correctly. We've encountered a bunch of cases where some setups do not actually do vsync and thus return instantly and create high CPU load. So I think some form of detection as to whether vsync is working may be necessary. |
But it's working when relying on vsync just a little bit later, by using the |
Also, I don't think vsync is broken on my hardware per se, because a) it can be "fixed" with the above workaround, and b) I don't experience any issues when using Pyxel. I tried the same example to test smooth screen updates with Pyxel and with Nico: import pyxel
x = 0
def update():
pass
def draw():
global x
pyxel.cls(0)
pyxel.line(x, 0, x, 128, 7)
x += 1
x %= 128
pyxel.init(128, 128, title="Pyxel", fps=60)
pyxel.mouse(True)
pyxel.run(update, draw) import nico
var x = 0
proc gameInit() =
# setVSync(false)
setColor(8)
proc gameUpdate(dt: Pfloat) =
discard
proc gameDraw() =
cls()
line(x,0,x,64)
x += 1
x = x mod 128
nico.init("nico", "test")
fixedSize(true)
integerScale(true)
nico.createWindow("nico", 128, 128, 4)
nico.run(gameInit, gameUpdate, gameDraw) Skipped screen updates are immediately visible by jumps in the moving line when uncomminting The Pyxel version runs with 1.5% CPU usage out of the box (also smooth). I use the same I haven't looked into what Pyxel does different from Nico regarding the SDL configuration. |
I noticed that the CPU usage increases over time when using
setVSync(true)
, which is the default. This happens even for a simple example likelines.nim
.When using
setVSync(false)
, this does not happen, but of course this has the drawback of tearing or not smooth screen updates.The main difference when using
setVSync(false)
is inproc run*()
where waiting is done manually usingdelay()
. However, it seems that when solely relying on vsync, CPU usage seems to increase over time.As a solution this pull request adds a delay(1) even for the vsync case, if
sleepTime
is not smaller than 1.0 ms. This fixes the reported CPU usage problem.