[英]Why does compare_exchange_strong fail with std::atomic<double>, std::atomic<float> in C++?
I am reading C++ Concurrency in Action Chapter 5. This chapter says,我正在阅读 C++ Concurrency in Action 第 5 章。本章说,
Note that although you can use std::atomic<float> or std::atomic<double>, because the built-in floating point types do satisfy the criteria for use with memcpy and memcmp, the behavior may be surprising in the case of compare_exchange_strong.
请注意,尽管您可以使用 std::atomic<float> 或 std::atomic<double>,因为内置浮点类型确实满足与 memcpy 和 memcmp 一起使用的标准,但在比较交换强。 The operation may fail even though the old stored value was equal in value to the comparand, if the stored value had a different representation.
即使旧存储值的值与比较值相等,如果存储值具有不同的表示形式,操作也可能失败。 Note that there are no atomic arithmetic operations on floating-point values.
请注意,浮点值没有原子算术运算。 You'll get similar behavior with compare_exchange_strong if you use std::atomic<> with a user-defined type that has an equality-comparison operator defined, and that operator differs from the comparison using memcmp—the operation may fail because the otherwise-equal values have a different representation.
如果您将 std::atomic<> 与定义了相等比较运算符的用户定义类型一起使用,并且该运算符与使用 memcmp 的比较不同,那么您将获得与 compare_exchange_strong 类似的行为 - 操作可能会失败,因为否则 -相等的值有不同的表示。
But I don't understand why it is.但我不明白为什么会这样。
If float and double can use memcpy and memcmp, what is the matter to do atomic operation like compare_exchange_strong?如果 float 和 double 可以使用 memcpy 和 memcmp,那么像 compare_exchange_strong 这样的原子操作有什么问题?
I can't use compare_exchange_weak also?我也不能使用 compare_exchange_weak 吗?
Above paragraph, what does "difference representation" mean?以上段落,“差异表示”是什么意思?
IEEE-754 floats use a signed/magnitude format to determine the sign of the mantissa. IEEE-754 浮点数使用有符号/大小格式来确定尾数的符号。 That is, there's a sign bit, and then there are bits that represent a positive number.
也就是说,有一个符号位,然后有代表一个正数的位。 If the sign bit is set, then the number is interpreted as negative.
如果设置了符号位,则该数字被解释为负数。
Of course, if all of the numeric (and exponent) bits are 0, and the sign bit is set, then that yields the "number" -0.0.当然,如果所有的数字(和指数)位都是 0,并且符号位被设置,那么就会产生“数字”-0.0。 As far as real-world human math is concerned, there is no "negative 0".
就现实世界的人类数学而言,没有“负0”。 So logically, such a number should be treated as equivalent to +0.0.
所以从逻辑上讲,这样的数字应该被视为等于+0.0。 And normal floating-point comparison logic does exactly that.
而普通的浮点比较逻辑正是这样做的。 But these two equivalent values are stored with different binary representations;
但这两个等价值以不同的二进制表示形式存储; one has the sign bit set;
一个设置了符号位; the other does not.
另一个没有。
So if you do a comparison of the binary representation of two floating point values (which is what the atomic_compare_*
operations will do), then -0.0 will not be considered equal to +0.0.因此,如果您对两个浮点值的二进制表示进行比较(这是
atomic_compare_*
操作将执行的操作),则 -0.0不会被视为等于 +0.0。
There are other cases where IEEE-754 equality testing can go wrong, but this is the simplest one to explain.还有其他情况下 IEEE-754 相等性测试可以 go 错误,但这是最简单的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.