To be precise, I only need to increase a double by another double and want it to be thread safe. I don't want to use mutex for that since the execution speed would dramatically decrease.
Asked
Active
Viewed 7,180 times
10
-
related: [Atomic double floating point or SSE/AVX vector load/store on x86_64](https://stackoverflow.com/questions/45055402/atomic-double-floating-point-or-sse-avx-vector-load-store-on-x86-64). Basically the same answer as this, but with x86 asm details. (Some compilers are fairly inefficient getting data from XMM to integer for `compare_exchange` or even load/store with `atomic
`, unfortunately.) – Peter Cordes Sep 04 '17 at 06:46
2 Answers
18
As a rule, the C++ standard library tries to provide only operations that can be implemented efficiently. For std::atomic
, that means operations that can be performed lock-free in an instruction or two on "common" architectures. "Common" architectures have atomic fetch-and-add instructions for integers, but not for floating point types.
If you want to implement math operations for atomic floating point types, you'll have to do so yourself with a CAS (compare and swap) loop (Live at Coliru):
std::atomic<double> foo{0};
void add_to_foo(double bar) {
auto current = foo.load();
while (!foo.compare_exchange_weak(current, current + bar))
;
}

Casey
- 41,449
- 7
- 95
- 125
-
Thank You for the answer, I didn't realize that in order to do that (add two doubles thread safely) I would need such dirty (or at least it looks like it to me) workaround. – Noozen Apr 16 '14 at 18:12
-
1I am a little confused. Why will this code not go into an infinite loop if foo != current due to foo being modified by another thread between the load and the CAS? – Joe Nov 17 '15 at 01:55
-
2@Joe `compare_exchange_weak` takes its first argument by reference, and updates it to the observed value on failure. So if the CAS fails becayse `foo != current` the loop calculates a new `current + bar` from the updated `current` and tries again. – Casey Nov 17 '15 at 03:26
-
-1
So use the integral atomic as a memory barrier. Here's a page with source and explanation: http://preshing.com/20121019/this-is-why-they-call-it-a-weakly-ordered-cpu/

MagikWorx
- 342
- 1
- 10
-
A memory barrier only helps with ordering, not atomicity. This is why you need a CAS (or LL/SC) to make the entire read-modify-write atomic. – Peter Cordes Sep 04 '17 at 05:04