On Tue, Apr 21, 2015 at 9:38 AM, Saúl Ibarra Corretgé <[email protected]> wrote:
> On 04/20/2015 04:01 PM, Andrius Bentkus wrote:
>> While toying around with libuv I have found out that the epoll timer has
>> a resolution of only a second which creates a drift.
>>
>> If we do something like
>>
>> ```js
>> var count = 0;
>> var last = count;
>>
>> setInterval(function () {
>>   count++;
>> }, 1); // every millisecond
>>
>> setInterval(function () {
>>   console.log(count - last);
>>   last = count;
>> }, 1000); // after a second
>> ```
>>
>> With libuv (this is nodejs code, but the same would hold true for
>> C/libuv code) we get < 1000 events per second. On my machine its around
>> ~923 events.
>>
>> Now this is impossible to solve with epoll having a timeout based on
>> milliseconds and not nanoseconds, but I just wanted to post this:
>> https://github.com/famz/linux/tree/epoll_pwait1
>>
>> This patch introduces an epoll api which works on nano second resolution
>> and would allow us to get the thing running sufficiently fine graind.
>> The author wants that feature to get into the kernel for qemu.
>>
>> Here is the entire discussion on the linux kernel mailing list
>> http://thread.gmane.org/gmane.linux.kernel.api/8250
>>
>> I just wanted to post this so we would keep a look out for when the
>> feature hits the kernel
>>
>
> Nice!
>
> When drafting the uv_timeout API someone (Ben IIRC) told me that we
> could make the timeout a double, and thus support sub-millisecond
> precision, where possible. AFAIK we could have sub-millisecond precision
> if we use a timerfd instead of passing the timeout to epoll_wait/pwait.
> We'd arm a single timerfd per loop, witht he value of the closest timer,
> and add it to the epoll set, and then we'd call epoll_wait/pwait with a
> NULL timeout.
>
> I'm not sure if there are limitations I'm not aware of here, but that
> could be a start. The new epoll API could be supported as well, but
> before that the user facing APIs need to support specifying
> sub-millisecond precision.

That was me, yes. :-)

There is a minor complication in that the linux kernel has a concept
of 'timer slack'; to increase throughput, the kernel tries to coalesce
timer events by postponing process wake-up.  The default slack is 50
microseconds, or 1/20,000th of a second; probably fast enough for most
applications.

You can disable it on a per-thread basis with
`prctl(PR_SET_TIMERSLACK, 1)`.  Zero resets it.

However, the slack also affects the granularity of the futex() system
call, in turn affecting library functions that are built on top of it,
like pthread_cond_timedwait() and sem_timedwait().  Depending on your
viewpoint, that may or may not be a good thing.

-- 
You received this message because you are subscribed to the Google Groups 
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Reply via email to