使用OpenMP的x86上的Atomic Minimum



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

在OpenMP规范中,我没有发现C++,但Fortran版本似乎支持它。有关详细信息,请参阅v3.1的2.8.5。对于C++,它表示

binop是+、*、-、/、&、^、|之一<lt;,或>>。

但是对于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。)

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

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

最新更新