|Issue 428:||Pyglet Clock Timings - Problem with schedule_interval|
|5 people starred this issue and may be notified of changes.||Back to list|
I believe there is a problem with the underlying calculations for schedule_interval specifically when it's running alongside something that is scheduled every frame (presumbly because this adds extra tick time). On my system the following code outputs dt values of average 30ms rather than 16ms, infact it's pretty much never 16ms. with: --- import pyglet window = pyglet.window.Window(800, 600, vsync=True) def update(dt): if dt > 0.017: print dt def idle(dt): pass pyglet.clock.schedule_interval(update, 1/60.) pyglet.clock.schedule(idle) pyglet.app.run() --- Having looked at the underlying code for how schedule_interval works I think it is incorrectly setting the items next_ts (the next time it will be scheduled). Within clock.py and the call_scheduled_functions method there it actually calculates the next_ts at one point and then will immediatly change a few lines down. See "item.next_ts = ts + item.interval" Which means it will set the next_ts to be the current time (well the current tick time) plus our interval, since time would have elapsed since this call is made it means it is always going to be more than just the interval from the last time it ran. For example if the "last time" was 100 "current time" was 110 then the "next time" would get calculated to be 126 and each time it comes through it will be slightly more than the just a 16ms interval between. Instead it should be the "last time" + the interval so in this case 116. I'm not sure if i've explained that very well but the timings do come across very strange when using schedule_interval in this manner. I have refactored this code (attached is the entire clock.py with comments see line 307) to how I think it should be working and given it some tests, it looks on the whole much more well behaved. I still do see a fair amount of higher than 20ms values but not nearly as much and these could be the results from timer inaccuracies. System Information: Windows 7 64bit Quad Core (Q6600) Python 2.6.3 Pyglet version is straight from the main trunk however I was experienceing this on 1.1.3 as well (major difference though is the trunk version correctly uses time.clock on windows and not time.time)
Jun 29, 2009
I have to unfortuantly conclude that my above reasoning was incorrect. I was still getting some odd timings so I sat down and thought about it some more, what is currently being done does make sense. If the newly calculated next scheduled time is not going to happen we have to set it to be the current time + the interval or that instance won't get called. I am still having unreliably timings though, a large quantity of greater than 30ms however I have not got to the bottom of this. Although I realise my original summary of the problem was incorrect I still think there is something amiss with these timings and therefore still an issue, I will update if I discover anything.
Aug 14, 2009
AFAIK, the accuracy of Pyglet's timing under windows is limited by the reliability and resolution of the windows timing functions, which are usually accuracte to no more than 10ms. Things can get even more hairy when multiple cores are used. Thus, some of your issue may relate to that. See a previous discussion on pyglet- users.  http://groups.google.com/group/pyglet- users/browse_thread/thread/9f53ce8ee97bf63/cf1b06cee5c9a490? lnk=gst&q=schedule_interval#cf1b06cee5c9a490
Aug 16, 2009
In the example, you're asking for a "synchronized" window (vsync=True). If your vertical refresh rate is around 30Hz, then you cannot pretend to be faster than 1/30. (~ 0.333). Can you try the same with vsync=False ?
Aug 20, 2009
Hi, It's been awhile since I looked at this issue myself so I'm a little foggy as to the details now. I don't think it's related to vsync though I appreciate that it would effect the timings. I actually think it's more related to schedule_interval, that for me on my system did not produce accurate timings and the code used is different to the standard schedule function. Additionally clock.py was changed in the trunk after 1.3 was released for windows to use time.clock for timings which uses QueryPerformanceCounter under the hood which is far more reliable on Windows. This may have had an effect on initial timing results. In the end I decided to effectively just update as fast as I can with vsync disabled and using the pyglet.clock.schedule function. This seems to produce better timings at any rate. I do still need to do some more proper testing on various systems to see if there is still an issue.
Aug 21, 2009
Please try the maintenance branch r2516 and see if it helps.
Aug 22, 2009
As far as I can tell that branch does exactly what the trunk is doing which is what i'm running this against. Which is to use time.clock for underlying timings on windows. I just did a quick run of example code with schedule_inteval attempting to update at an interval of 1/60. which as stated before in my eyes should give around 16ms with some variance, instead this is actually giving me more a steady 20ms with variance. This is only on this machine i've tested with at the moment though.
Aug 22, 2009
I've been looking into a similar issue (issue 445) and there's notes collected there that may be helpful. It's looking to me like the windows clock should be revamped in 1.2.
Apr 28, 2012
Any windows users willing to have a crack at this?
Jul 21, 2012
Hello, I was looking at the new pyglet (1.2 alpha1) release and it occurred to me that this bug I made was kind of left hanging. Using my original timer script above, I do still get 30ms update from schedule_interval with 1/60, however this is in windowed mode, in fullscreen mode I do get more likely lower timings with a few exceptions. Looking about there is a lot of confusion regarding this however, I've seen a few other posts talk about the fact they get lower timings when using schedule_interval when they expect to get it as high as they requested. If it's just a case that schedule_interval is not guaranteed to give you exactly the interval you wanted, perhaps a note in the documentation to say this, is all that is needed. Hope that at least provides some extra information on this old bug. It may be worth closing for now and if it crops up again (as perhaps a more substantial problem) then it can be re-examined in a new light.
Dec 4, 2012
Are you really sure it's not just a matter of vsync being enabled? I had the same problem, ~30ms dt's no matter how small I set the schedule_interval, until I disabled vsync. Remember that the run loop that drives the pyglet.clock timers is what calls the page flip, so it blocks (I assume) until the flip completes, thus the timers won't update any faster than your refresh rate (and in fact update somewhat slower, I'm guessing because of the wait for the next frame?). When I turn off vsync, schedule_interval can run in excess of 1000 ticks a second on my system.
Dec 12, 2012
Going by comment 10 and no other recent activity I'm closing this issue.
|► Sign in to add a comment|