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.
Otherwise, with these scheduling issues, the default eventloop 
implementation is practically unusable for games on Windows, which I think 
is a shame.
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.
timeGetTime/timeBeginPeriod appears to be both high-res, stable and 
precise, so I was wondering what the rationale is for not using these APIs?

In asyncio, would an API to modify the timer implementation be applicable?
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.
Generally, having to add hacks for Windows is not very attractive when e.g. 
Twisted works out of the box.

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.
I will do some more testing, and see if I can come up with a solution 
without changing the timer implementation.

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] <javascript:>> 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/
>>>> show/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)
>>>
>>

Reply via email to