On Fri, Jan 24, 2014 at 10:48 AM, Victor Stinner <[email protected]>wrote:
> 2014/1/24 Ben Darnell <[email protected]>: > > The epoll change in > > > https://code.google.com/p/tulip/source/detail?r=5b7e17a75ba4b9bdaab5969a787e904137a53aee > > doesn't work. An integer number of milliseconds cannot be represented > > exactly as a floating-point number of seconds, so you lose precision when > > passing the adjusted timeout into epoll_wait and it rounds down to zero > > again: > > > >>>> int(math.ceil(0.0005 * 1e3) / 1e3) > > 0 > > PollSelector uses int(math.ceil(timeout * 1e3)), example: > > >>> int(math.ceil(0.0005 * 1e3)) > 1 > Yes, this one is fine because it converts to integer milliseconds and stays there instead of going back and forth. > > EpollSelector uses math.ceil(timeout * 1e3) * 1e-3, example: > > >>> math.ceil(0.0005 * 1e3) * 1e-3 > 0.001 > > And this value is passed to epoll.poll() which computes: timeout = > (int)ceil(dtimeout * 1000.0) > As long as epoll.poll is using ceil, the rounding in EpollSelector is unnecessary. The question is whether this rounding solves the problem for python builds where this has not yet been fixed. I had confused myself into thinking it wasn't working, but I had the math wrong and missed one of the factors of 1000. I'm not sure whether it's generally safe to assume that the repeated multiplication and division doesn't introduce rounding errors, but it does appear to work at least for factors of 1e3 and 1e6. > > But it looks like all these rounding functions are not enough: > http://bugs.python.org/issue20311#msg208927 > > I proposed a different patch reverting my changes in select and > selectors module and use instead a new granularity to round timings > only in asyncio, in BaseEventLoop._run_once(). The granularity uses > not only the resolution of the selector, but also the resolution of > the clock. It has at least an impact on Windows (clock resolution: > 15.6 ms) and FreeBSD (kqueue resolution: 1e-9, clock: 11-e9). > I think using max(requested_timeout, resolution) is a better solution than using math.ceil, but I'm surprised that the system clock resolution matters as well (the underlying system call should be taking care of this). -Ben > > Victor >
