如何在C ++中为共享计数器实现简单的比较和交换 [英] how to implement simple Compare And Swap in C++ for shared counter
问题描述
我正在尝试没有锁的并发性.因此,我试图为共享变量计数器实现简单的Compare和Swap(cas).我试图创建10个线程,并希望使用CAS将每个线程的计数器值增加1.因为CAS会存储旧值并与当前值进行比较,并且仅在值不变的情况下进行更新.在[这里]我尝试实施CAS,但是无法正确执行.如何在C ++中为计数器共享变量实现CAS?
I am trying to learn concurrency without locks. Thus I am trying to implement simple Compare and Swap(cas) for shared variable counter.I tried to create 10 threads and want to increase the counter value by each thread by 1 using CAS. since CAS store the old value and compare with the current value and update only if the values are unchanged. looking[here] I tried to implement the CAS, but couldn't get it right. How to implement CAS for counter shared variable in c++?
#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;
}
推荐答案
您的解决方案是正确的.
Your solution is correct.
另一种方法是使用增量,请参见 std::atomic::operator++()
或 fetch_add(1, std::memory_order_acq_rel)
.这两个不需要繁忙的等待循环.
Another way is to use the increment, see std::atomic::operator++()
or fetch_add(1, std::memory_order_acq_rel)
. These two do not require a busy waiting loop.
std::atomic<int> count = 0
的初始化存在编译器错误.修复:
There is a compiler error with the initialization of std::atomic<int> count = 0
. Fix:
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
内在函数提高了代码检测锁释放的速度,并提供了显着的性能提升.
The
pause
intrinsic is used in spin-wait loops with the processors implementing dynamic execution (especially out-of-order execution). In the spin-wait loop, thepause
intrinsic improves the speed at which the code detects the release of the lock and provides especially significant performance gain.
下一条指令的执行被延迟特定于实现的时间量. pause
指令不会修改体系结构状态.对于动态调度,pause
指令减少了退出自旋循环的代价.
The execution of the next instruction is delayed for an implementation-specific amount of time. The pause
instruction does not modify the architectural state. For dynamic scheduling, the pause
instruction reduces the penalty of exiting from the spin-loop.
请参见使电源和性能睡眠循环受益了解更多详细信息和基准.
See Benefitting Power and Performance Sleep Loops for more details and benchmarks.
这篇关于如何在C ++中为共享计数器实现简单的比较和交换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!