3

问题在于compare_exchange_strong返回 false,尽管基础数据等于expected. 例如:

std::atomic<data> ptr;
...
auto ptr_data = ptr.load();
bool cmp_result = memcmp(&ptr_data, &expected, sizeof(ptr_data));
bool cas_result = ptr.compare_exchange_strong(expected, desired);
assert(cas_result || !cmp_result);

data是一个 128 位的 POD。ptr.is_lock_free()返回真。这是以单线程方式测试的。cas_result永远是假的,cmp_results永远是真的。

编译使用 Intel 的 C++ 编译器,版本 16 更新 2。在 Linux 上,libstdc++ 版本 5.3.1。64 位二进制。
完全相同的代码在 Windows 上编译时可以正常工作,具有相同的 ICC16,但作为 32 位代码。这让我相信这是 stdlib 实现的怪癖。

谢谢

4

1 回答 1

1

我在使用的结构上也遇到过这种情况。我认为这是由于对齐问题而插入的填充位以及 compare_exchange 对两个值进行按位比较的事实引起的。

在我的机器上,字/指针大小是 8 个字节,我的结构是这样的:

struct s {
    int i;
    void *ptr;

};

它仅使用 12 字节来表示其内容(ptr 为 8 字节,int 为 4),但它的大小为 16 字节(sizeof(s) == 16)。我所做的是将结构更改为:

struct s {
    long long i;
    void *ptr;
};

因为 long long 在我的机器上是 8 个字节,所以这个版本有 16 个字节大小,它们都用来表示实际值(没有填充位)。

我在阅读此答案后看到了问题,这可能更详细。

于 2020-06-22T17:03:56.720 回答