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)

Reply via email to