c++floating-pointatomiccompare-and-swapstdatomic

Why isn't atomic double fully implemented


My question is quite simple. Why isn't std::atomic<double> implemented completely? I know it has to do with atomic RMW (read-modify-write) access. But I really don't see, why this shouldn't be possible on a double.

It's specified that any trivially copyable type can be used. And of course double is among them. So C++11 requires the basic operations (load, store, CAS, exchange, etc.) that you can use with any class type.

However, on integers an extra set of operations is possible (fetch_add, ++, +=, etc).

A double differs very little from these types. It's native, trivially copyable, etc. Why didn't the standard include the double with these types?


Update: C++20 does specialize std::atomic<T> for floating-point types, with fetch_add and sub. C++20 std::atomic<float>- std::atomic<double>.specializations But not atomic absolute-value (AND) or negate (XOR).

Editor's note: Without C++20 you can roll your own out of CAS; see Atomic double floating point or SSE/AVX vector load/store on x86_64 for portable examples; atomic<double> and float are lock-free on most C++ implementations.


Solution

  • std::atomic<double> is supported in the sense that you can create one in your program and it will work under the rules of C++11. You can perform loads and stores with it and do compare-exchange and the like.

    The standard specifies that arithmetic operations (+, *, +=, &, etc.) are only provided for atomics of "integral types", so an std::atomic<double> won't have any of those operations defined.

    My understanding is that, because there is little support for fetch-add or any other atomic arithmetic operations for floating point types in hardware in use today, the C++ standard doesn't provide the operators for them because they would have to be implemented inefficiently.

    (edit). As an aside, std::atomic<double> in VS2015RC is lock-free.