Summary:
Unless a service is overloaded, it should be able to clear
its queue frequently. When this happens, threads fall asleep until
more work is available in the queue. Waking up threads in LIFO
order gives us a lot of benefits. First, threads that were most
recently active are more likely to be mapped to the same cpu core
and thereby experience better L1 cache hit rate. Second, we can
madvise away jemalloc arenas on very idle threads. If we wake up
threads in FIFO order, we will never get a thread to remain idle
long enough for this to be worthwhile.
folly::LifoSem does just that. Benchmark in which the queue is
allowed to drain show that we get a substantial increase in
throughput by waking up threads in LIFO order.
Test Plan:
QueueBenchmark results summary:
As expected, benchmarks run faster in the case where the queue is
able to frequently drain itself, particularly in cases where the
number of threads is large. Benchmarks run slower when the
consumers cannot keep up with the producers, particularly when we
reach the queue capacity and we need to synchronize between
producers and consumers. However, in this case I think we care
less about the overhead of the queue itself and more about how
quickly we can shed the actual underlying load.
Reviewed By: davejwatson@fb.com
FB internal diff:
D1298343
#include <folly/AtomicStruct.h>
#include <folly/detail/CacheLocality.h>
+// Ignore shadowing warnings within this file, so includers can use -Wshadow.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+
namespace folly {
namespace detail {
} // namespace folly
+# pragma GCC diagnostic pop
#endif
}
/// Returns the LifoSemHead that results from pushing a new waiter node
- inline LifoSemHead withPush(uint32_t idx) const {
+ inline LifoSemHead withPush(uint32_t _idx) const {
assert(isNodeIdx() || value() == 0);
assert(!isShutdown());
- assert(idx != 0);
- return LifoSemHead{ (bits & SeqMask) | IsNodeIdxMask | idx };
+ assert(_idx != 0);
+ return LifoSemHead{ (bits & SeqMask) | IsNodeIdxMask | _idx };
}
/// Returns the LifoSemHead with value increased by delta, with