8

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]);
  }
}

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

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

  int x = ...;
  int y = ...;
  while(y < val[x])
    val[x] = y;

但这不是原子操作。

所有较新的 GPU 都具有此功能,而我在 CPU 上缺少它。(有关 OpenCL,请参见 atom_min。)

4

1 回答 1

5

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

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

于 2012-09-04T08:19:38.203 回答