OpenMP 原子比较和交换

OpenMP atomic compare and swap

我在并行区域内有一个共享变量 s 和一个私有变量 p

如何自动执行以下操作(或至少比使用 critical 部分更好):

if ( p > s )
    s = p;
else
    p = s;

即,我需要更新全局最大值(如果局部最大值更好)或读取它,如果它已被另一个线程更新。

OpenMP 5.1 引入了 compare 子句,允许进行比较和交换 (CAS) 操作,例如

#pragma omp atomic compare
if (s < p) s = p;

结合capture子句,你应该可以达到你想要的效果:

int s_cap;

// here we capture the shared variable and also update it if p is larger
#pragma omp atomic compare capture
{
   s_cap = s;
   if (s < p) s = p;
}

// update p if the captured shared value is larger
if (s_cap > p) p = s_cap;

唯一的问题? 5.1 规范非常新,截至今天 (2020-11-27),none 个广泛使用的编译器,即 Godbolt, supports OpenMP 5.1. See here 上可用的编译器或多或少是最新的列表.添加 compare 仍列为 Clang 的 OpenMP 页面上的无人认领任务。 GCC 仍在努力提供完整的 OpenMP 5.0 支持,trunk 基于 Godbolt 的构建无法识别 compare。英特尔的 oneAPI 编译器可能支持也可能不支持它 - 它在 Godbolt 上不可用,我无法用它来编译 OpenMP 代码。

你现在最好的选择是使用 atomic capture 结合编译器特定的 CAS 原子,可能在一个循环中。