Skip to content

Commit

Permalink
Use a less constraining memory order for all "update" operations on C…
Browse files Browse the repository at this point in the history
…ounter/Gauge.

Updates on metrics is something that happens much more often than
collecting operations, and it doesn't require strong atomic guarantees
(ie if two threads update a metric at the same time, we might accept
that it's not always the very last update that is being kept in the
metric). We sacrifice a bit correctness in case of multithread
concurrent updates (which is a rather rare scenario) for better
performances all the time (ie even with a single thread, or not
concurrent updates).
  • Loading branch information
Romain-Geissler-1A committed Dec 9, 2022
1 parent 66e60b4 commit cfb37a3
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions core/src/gauge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@ void Gauge::Decrement() { Decrement(1.0); }

void Gauge::Decrement(const double value) { Change(-1.0 * value); }

void Gauge::Set(const double value) { value_.store(value); }
void Gauge::Set(const double value) {
value_.store(value, std::memory_order_relaxed);
}

void Gauge::Change(const double value) {
#if __cpp_lib_atomic_float >= 201711L
value_.fetch_add(value);
value_.fetch_add(value, std::memory_order_relaxed);
#else
// Pre-C++ 20 fallback: busy loop (which might be more expansive than using
// fetch_add).
auto current = value_.load();
while (!value_.compare_exchange_weak(current, current + value)) {
auto current = value_.load(std::memory_order_relaxed);
while (!value_.compare_exchange_weak(current, current + value,
std::memory_order_relaxed,
std::memory_order_relaxed)) {
// intentionally empty block
}
#endif
Expand Down

0 comments on commit cfb37a3

Please sign in to comment.