On Sat, May 17, 2014 at 2:35 AM, Mathias Kærlev <[email protected]> wrote:
> That seems like a cop-out to me. > > I get that GetTickCount64 does not have high precision, but you could > consider using a timeGetTime/GetTickCount64 hybrid (like in GLib) for > asyncio. > If you want to take a stab at contributing we will consider it. > Otherwise, with these scheduling issues, the default eventloop > implementation is practically unusable for games on Windows, which I think > is a shame. > TBH games weren't high on our list of use cases. (I think Glyph mentioned that Twisted was born out of his desire to write a game, but he immediately added that that is no longer Twisted's goal.) > Obviously, I agree that a precise, stable (i.e. not QPC) monotonic clock > would be the only proper timer solution, but ultimately, it should not come > at the expense of usability. > But not everybody has the same needs, so what's more usable for you may be less usable for someone else. > timeGetTime/timeBeginPeriod appears to be both high-res, stable and > precise, so I was wondering what the rationale is for not using these APIs? > I don't know, but the most likely answers is that nobody considered them (unlike PEP 418 says otherwise). > In asyncio, would an API to modify the timer implementation be applicable? > This solution makes the most sense to me. > Just changing loop.time will not work, as you would also have to change > loop._clock_resolution, so now we're in the business of monkey-patching > eventloop and implementation-specific details. > Agreed. I guess we'd need to define and implement a new API loop.set_clock(time_func, clock_resolution). > Generally, having to add hacks for Windows is not very attractive when > e.g. Twisted works out of the box. > You are welcome to switch back to Twisted. ;-) > > About the original example I posted, it seems like the stability problems > only occur if the 100 FPS loop is added. > Perhaps the issue could be rectified if the eventloop was more clever with > its scheduling? > libuv also seems to use GetQueuedCompletionStatus timeouts to adjust the > timer, so I think there may be room for improvement with the timer in the > Windows eventloop. > If you can make it better by all means don't sit on your patches but send them our way! > I will do some more testing, and see if I can come up with a solution > without changing the timer implementation. > That would be much appreciated. > > Thanks, > Mathias > > Den lørdag den 17. maj 2014 09.52.54 UTC+2 skrev Victor Stinner: >> >> Hi, >> >> I had very very long discussion about timer granularity and choose the >> "right" clock in Python and in asyncio. See for example the PEP 418 to >> learn why time.monotonic() has such very low precision. >> >> I don't want to change the default clock of asyncio or change >> time.monotonic(). As Guido wrote, it's easy to change the clock of an event >> loop. Try loop.time = myclock. >> >> Victor >> >> Le samedi 17 mai 2014, Mathias Kærlev <[email protected]> a écrit : >> >> So after some quick tests, it's apparent that switching out >>> time.monotonic() with either time.clock() or time.time() completely fixes >>> the issue (so the framerate is always between 49~50). >>> For my application, I can probably subclass the eventloop and switch out >>> the timer implementation, but ideally, this should be fixed upstream >>> somehow. >>> I never had this issue with Twisted, even though I think Twisted uses >>> time.time() with some heuristics to detect time drift and similar issues. >>> Personally, I've always found a combination of timeGetTime() and >>> timeBeginPeriod(1) to yield a very stable timer on Windows (especially for >>> games), but perhaps you have greater insight into the issue. >>> >>> Thanks for the help! Is there any chance this will be fixed in an >>> upcoming asyncio release? >>> >>> Mathias >>> >>> Den lørdag den 17. maj 2014 06.31.18 UTC+2 skrev Guido van Rossum: >>>> >>>> This could well be timer granularity on Windows; this has been a big >>>> problem for the unittests too. Could you try with a different timer? It >>>> should be easy to change the timer function. >>>> >>>> On Friday, May 16, 2014, Mathias Kærlev <[email protected]> wrote: >>>> >>>>> Hi everyone >>>>> >>>>> I'm currently porting some code from Python 2.7 with Twisted to Python >>>>> 3.4 with asyncio. So far, it's been a pleasant experience. >>>>> However, my application in question is a game server which needs to >>>>> run a 50FPS update loop to simulate the game world. >>>>> When running multiple update loops, I start to get some very unstable >>>>> behavior, where the actual delay between a call_later call and the time it >>>>> fires wobbles between the specified delay and half the delay. >>>>> >>>>> Please see the following example: http://bpaste.net/sho >>>>> w/Cxn0jxqufnvNk7qL8MnJ/ >>>>> In the example, I run two update loops: one on 50FPS, and one on >>>>> 100FPS. I only monitor the update loop running at 50 FPS. >>>>> Yet, on Windows 7, I get the following output: http://bpaste.net/show >>>>> /XKp4LtKpEsXWxacZjQlc/ >>>>> The framerate is very wobbly, going between ~100 FPS and ~50 FPS (the >>>>> 100 FPS LoopingCall is not being logged, of course). >>>>> >>>>> Is this a bug in my LoopingCall class, or is it a problem with the >>>>> eventloop timer granularity? >>>>> >>>>> This is using the asyncio release found in stdlib on Python 3.4, by >>>>> the way. >>>>> >>>>> Thanks for the help! >>>>> >>>>> >>>> >>>> -- >>>> --Guido van Rossum (on iPad) >>>> >>> -- --Guido van Rossum (python.org/~guido)
