如何在C ++中为共享计数器实现简单的比较和交换 [英] how to implement simple Compare And Swap in C++ for shared counter

查看:137
本文介绍了如何在C ++中为共享计数器实现简单的比较和交换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试没有锁的并发性.因此,我试图为共享变量计数器实现简单的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, the pause 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆