检查前置条件是否有原子增量,原子值小于指定值?

时间:2012-12-08 13:55:49

标签: c++ c++11 atomic atomic-swap stdatomic

是否在新标准C ++原子增量操作中使用检查前置条件增加值之前,原子值是否小于指定值?

我可以比以下代码更容易,更快地完成吗?

int atomic_inc(std::atomic_int& val, int less_than) {
 int new_val;
 int old_val = val.load();
 do
 {
   if (old_val > less_than) return old_val;
   new_val = old_val + 1;
 } while (!val.compare_exchange_weak(old_val, new_val));

 return new_val;
}

如果有人不知道compare_exchange_weak是如何工作的: compare_exchange_weak读取val,与old_val进行比较,如果它们不相等,则将val保存到old_val。如果它相等则将new_val保存到val。

3 个答案:

答案 0 :(得分:1)

不,没有特别支持递增小于值的值。您的代码尽可能高效。 C ++ 11中没有等待的变体

无限数量的可能“增量如果X”模式。硬件制造商决定“只要不改变就增加”是他们唯一需要支持的东西。

理论上你可以为它创建一个带有特殊汇编代码的硬件平台,但是C ++ 11并没有直接针对它。

答案 1 :(得分:1)

我过去做过的事情可能会对你有用,具体取决于你使用的是什么。

如果您可以假设val不会经常剪辑 - 那么可能优化不执行CAS也不会为您节省太多 - ,您可以盲目地增加值和阅读后调整它:

int atomic_inc(std::atomic_int& val, int less_than) {
    return std::min(++val, less_than);
}

然后,如果需要,偶尔会将val剪切回less_than,这通常足以让您不必担心int溢出,而且您是黄金。

答案 2 :(得分:-3)

如果您正在使用线程,则可以使用互斥锁进行原子增量。在这种情况下,你就是这样做的:

全局声明并初始化互斥:

pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL)

在一个帖子中:

int atomic_inc(std::atomic_int& val, int less_than) {
    pthread_mutex_lock(&lock);
    int newVal = val.load();
    if (newVal < less_than)
        newVal++
    pthread_mutex_unlock(&lock);
    return new_val;
}

在修改任何其他线程中的val之前,您必须锁定和解锁互斥锁。

有关互斥锁的更多信息:http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SYNCHRONIZATION