Commit 9b5a1e4b authored by Marc Celani's avatar Marc Celani Committed by Dave Watson

Default to using folly::LifoSem

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
parent 6205123a
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
#include <folly/AtomicStruct.h> #include <folly/AtomicStruct.h>
#include <folly/detail/CacheLocality.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 folly {
namespace detail { namespace detail {
...@@ -424,4 +428,5 @@ struct IndexedMemPoolRecycler { ...@@ -424,4 +428,5 @@ struct IndexedMemPoolRecycler {
} // namespace folly } // namespace folly
# pragma GCC diagnostic pop
#endif #endif
...@@ -265,11 +265,11 @@ class LifoSemHead { ...@@ -265,11 +265,11 @@ class LifoSemHead {
} }
/// Returns the LifoSemHead that results from pushing a new waiter node /// 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(isNodeIdx() || value() == 0);
assert(!isShutdown()); assert(!isShutdown());
assert(idx != 0); assert(_idx != 0);
return LifoSemHead{ (bits & SeqMask) | IsNodeIdxMask | idx }; return LifoSemHead{ (bits & SeqMask) | IsNodeIdxMask | _idx };
} }
/// Returns the LifoSemHead with value increased by delta, with /// Returns the LifoSemHead with value increased by delta, with
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment