我正在使用OpenMP,并且需要使用fetch-and-add操作。然而,OpenMP没有提供适当的指令/调用。我想保持最大的可移植性,因此我不想依赖于编译器内置函数。
相反,我正在寻找一种方法来利用OpenMP的原子操作来实现这一点,但我已经陷入了僵局。这是否可以实现?请注意,以下代码几乎可以做到我想要的:
(如果我没记错的话),也可以用“比较并交换”问题来问,但是一个可以用另一个来实现。
相反,我正在寻找一种方法来利用OpenMP的原子操作来实现这一点,但我已经陷入了僵局。这是否可以实现?请注意,以下代码几乎可以做到我想要的:
#pragma omp atomic
x += a
几乎可以实现,但不完全,因为我真正需要的是x
的旧值。fetch_and_add
应该被定义为产生与以下代码相同的结果(只有非锁定操作):
template <typename T>
T fetch_and_add(volatile T& value, T increment) {
T old;
#pragma omp critical
{
old = value;
value += increment;
}
return old;
}
(如果我没记错的话),也可以用“比较并交换”问题来问,但是一个可以用另一个来实现。
atomic
并不像它的名字所承诺的那样,因为任何一个线程如果被修改了内存中的atomic
(在任何其他线程上),都需要重新缓存。因此频繁和重复的atomic
可能会降低性能(最好使用锁和缓冲区竞争写入)。 - Walter