Remove extraneous syscalls if NotificationQueue size() > 1
authorDave Watson <davejwatson@fb.com>
Fri, 11 Apr 2014 18:46:40 +0000 (11:46 -0700)
committerAnton Likhtarov <alikhtarov@fb.com>
Mon, 9 Jun 2014 22:35:16 +0000 (15:35 -0700)
commitcf214a5ba3faa378a1758782c533f4aeaf27b158
tree7feb0271108fee4214feac84f7e9d77f4f76e201
parent5a5aee33a6c2c9c64fc0edc08199f7a509dcb525
Remove extraneous syscalls if NotificationQueue size() > 1

Summary:
Currently notification queue does 2 syscalls per item: one read, one write.  We only need the eventfd to notify to wake up the thread, so instead, if the thread is already awake, don't bother writing to the fd.

Benchmark shows that when the queue size() > 1, this is ~4x faster.

Note that this might be unfair if there are multiple consumers: I could imagine a situation where one thread eats all the wakeups written to the fd, so only one thread is actually working.  However, multiple consumers is a bad idea anyway, and I'd consider removing it entirely:  If the same fd is in multiple epoll() loops, _all_ epolls will wake up, resulting in a thundering herd problem.  I don't see any multiConsumer cases in fbcode

Using EFD_SEMAPHORE or not doesn't seem to matter, since hopefully we're only writing 1 wakeup per thread - and it wouldn't work at all for multiConsumer case.

Test Plan:
fbconfig thrift/lib/cpp/test:TNotificationQueueTest; fbamke runtests
fbconfig common/concurrency:QueueBenchmark
fbmake opt
QueueBenchmark --bm_min_iters=10000

Reviewed By: afrind@fb.com

Subscribers: doug, folly@lists, fbcode-common-diffs@lists, alandau, bmatheny, haijunz

FB internal diff: D1272872

Tasks: 2802758
folly/io/async/NotificationQueue.h