4

在新的标准 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。

4

3 回答 3

2

我过去做过的事情,可能对你有用,这取决于你用它做什么。

如果你可以假设它val不会经常剪辑——因此不做 CAS 的可能优化不会为你节省太多——你可以盲目地增加值并在阅读后调整它:

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

然后在需要时偶尔剪辑valless_than,通常足以让您不必担心int溢出,并且您是金色的。

于 2013-09-12T03:07:00.753 回答
1

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

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

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

于 2013-09-12T02:42:38.777 回答
-4

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

全局声明和初始化互斥锁:

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

于 2012-12-08T14:22:41.627 回答