我试图学习没有锁的并发性。因此,我试图为共享变量计数器实现简单的比较和交换(cas)。我试图创建10个线程,并希望使用CAS将每个线程的计数器值增加1。因为CAS存储旧值并与当前值进行比较,并且仅在值未更改时才更新。看[这里]我试图实施CAS,但无法做到正确。如何在c ++中实现计数器共享变量的CAS?
#include <iostream>
#include <thread>
#include <unistd.h>
#include <atomic>
std::atomic<int> count = 0;
std::mutex n_mutux;
void increase_counter(int i)
{
int old_value = count.load() ;
while (!count.compare_exchange_weak(old_value, old_value +1))
{
}
}
int main() {
int thread_num =10;
std::thread t[thread_num];
for(int i=0;i<thread_num;i++)
{
t[i]=std::thread((increase_counter),i);
}
for(int i=0;i<thread_num;i++)
{
t[i].join();
}
std::cout<<count;
}
答案 0 :(得分:3)
您的解决方案是正确的。
另一种方法是使用增量,请参阅std::atomic::operator++()
或fetch_add(1, std::memory_order_acq_rel)
。这两个不需要繁忙的等待循环。
std::atomic<int> count = 0
的初始化存在编译器错误。修正:
std::atomic<int> count{0};
效率稍高的CAS是:
void increase_counter(int i) {
int old_value = count.load() ;
while(!count.compare_exchange_weak(old_value, old_value + 1,
std::memory_order_release,
std::memory_order_relaxed))
_mm_pause();
}
pause
内在函数用于自旋等待循环,处理器实现动态执行(特别是乱序执行)。在自旋等待循环中,pause
内在函数提高了代码检测到锁定释放的速度,并提供了特别显着的性能提升。下一条指令的执行会延迟执行特定的时间。
pause
指令不会修改体系结构状态。对于动态调度,pause
指令减少了从自旋循环退出的惩罚。
有关详细信息和基准,请参阅Benefitting Power and Performance Sleep Loops。