使用OpenMP在x86上的原子最小值

B.S*_*.S. 7 c++ x86 atomic openmp minimum

OpenMP是否支持C++ 11的原子最小值?如果OpenMP没有可移植的方法:有没有办法使用x86或amd64功能?

在OpenMP规范中,我没有找到C++,但Fortran版本似乎支持它.有关详细信息,请参见v3.1的2.8.5.对于C++,它说明了

binop是+,*, - ,/,&,^,|,<<或>>之一.

但对Fortran来说,它说

intrinsic_procedure_name是MAX,MIN,IAND,IOR或IEOR之一.

如果您对更多上下文感兴趣:我正在寻找一个无互斥的方法来执行以下操作:

vector<omp_lock_t>lock;
vector<int>val;

#pragma omp parallel
{
  // ...
  int x = ...;
  int y = ...;
  if(y < val[x]){
    omp_set_lock(&lock[x]);
    if(y < val[x])
      val[x] = y;
    omp_unset_lock(&lock[x]);
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道您可以使用reduce算法计算最小值.我知道在某些情况下,这在很大程度上优于任何原子最小方法.但是,我也知道在我的情况下并非如此.

编辑:在我的情况下,一个选项稍微快一点

  int x = ...;
  int y = ...;
  while(y < val[x])
    val[x] = y;
Run Code Online (Sandbox Code Playgroud)

但这不是原子操作.

所有较新的GPU都具有此功能,我在CPU上遗漏了它.(请参阅OpenCL的atom_min.)

Lub*_*nov 5

C++ 的 OpenMP 规范不支持原子最小值。C++11 也不行。

我假设在您的算法中x,无论线程如何,都可以计算到任何有效索引。我建议更改您的算法,以便每个线程使用自己的val数组,然后在最后进行最终协调,也可以通过索引进行并行化。这将完全避免锁和原子操作,并为您提供为每个线程分离数据的好处,即没有机会进行错误的缓存共享。换句话说,它应该更快。