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 原子,可能在一个循环中。
我在并行区域内有一个共享变量 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 原子,可能在一个循环中。