From cfb37a32e9c7e5a1860f8aed3cd419d8065dae03 Mon Sep 17 00:00:00 2001 From: Romain Geissler Date: Thu, 8 Dec 2022 16:12:08 +0000 Subject: [PATCH] Use a less constraining memory order for all "update" operations on Counter/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). --- core/src/gauge.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/gauge.cc b/core/src/gauge.cc index a52d103a..d54e19c7 100644 --- a/core/src/gauge.cc +++ b/core/src/gauge.cc @@ -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