C++11: Atomic::compare_exchange_weak 是否支持非基元类型?



我有以下代码:

#include<atomic>
#include<iostream>
using namespace std;
struct Big{
int i;
int j;
int k[100];
};
int main(){
atomic<int> i;
cout<<i.load()<<endl;
i.store(20);
cout<<i.load()<<endl;
i.exchange(30);
cout<<i.load()<<endl;
atomic<Big> ab,expect,value;
ab.compare_exchange_weak(expect,value,memory_order_release,memory_order_relaxed);//error
return 0;
}

好吧,原子工作得很好,但我想看看compare_exchange_weak的无锁定功能是否适用于复杂的数据结构。用 --std=c++11 编译,它给了我:

error: no matching member function for call to 'compare_exchange_weak'
ab.compare_exchange_weak(expect,value,memory_order_release,memory_order_relaxed);
~~~^~~~~~~~~~~~~~~~~~~~~
candidate function not viable: no known conversion from 'atomic<Big>' to 'Big &' for 1st argument
bool compare_exchange_weak(_Tp& __e, _Tp __d,

所以我的问题:

  1. std::atomic::compare_exchange_weak 适用于复杂结构吗?

  2. 如果英特尔 CPU 硬件 CMPEXG 仅在 64 位长度的高速缓存行内工作,大于 8 字节的结构是否适用于 CMPEXG?还是原子操作吗?

  3. 如何修复我的程序?

谢谢。

std::atomic::compare_exchange_weak 适用于复杂结构吗?

是的,但有些条件包括平凡可复制和平凡可构造。

如果英特尔 CPU 硬件 CMPEXG 仅在 64 位长度的高速缓存行内工作,大于 8 字节的结构是否适用于 CMPEXG?

不。它不是那样工作的。如果你创建像你那里那样疯狂的大结构,你的代码将不会是"无锁的"。你的编译器将发出总线锁以确保线程安全,这就是为什么你永远不应该做你正在做的事情,大数据结构。你会把你的程序减慢数百倍,如果不是更多的话。考虑以原子方式交换指针。

还是原子操作吗?

不,它使用锁。您可以使用std::atomic::is_lock_free()对此进行测试

如何修复我的程序?

给你:

#include <atomic>
#include <iostream>
using namespace std;
struct Big {
int i;
int j;
int k[100];
};
int main() {
Big value, expect;
atomic<Big> ab;
ab.compare_exchange_weak(expect, value);
return 0;
}

最新更新