c++ - 使用 OpenMP 的 x86 上的原子最小值

标签 c++ x86 openmp atomic minimum

OpenMP 是否支持 C++11 的最小原子性?如果 OpenMP 没有可移植的方法:是否有某种方法可以使用 x86 或 amd64 功能来实现?

在 OpenMP 规范中,我没有找到任何适用于 C++ 的内容,但 Fortran 版本似乎支持它。详见 v3.1 的 2.8.5。对于 C++,它声明

binop is one of +, *, -, /, &, ^, |, <<, or >>.

但是对于 Fortran 来说

intrinsic_procedure_name is one of MAX, MIN, IAND, IOR, or 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 数组,然后在最后进行最后的协调,这也可以通过索引并行化。这将完全避免锁和原子,并为您提供分离每个线程数据的好处,即没有机会进行错误的缓存共享。换句话说,它应该更快。

关于c++ - 使用 OpenMP 的 x86 上的原子最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12255266/

相关文章:

c - OpenMP - 为什么比较次数会减少?

c++ - 自定义容器的自定义迭代器

c++ - 我怎样才能明智地分配静态 RtMidi 回调对象?

c++ - 是否可以在 C++ 中使用正则表达式?

assembly - GNU GRUB 为 Multiboot2 提供 "error: unsupported tag: 0xc"

c++ - 使用 SIMD 将 10 位值打包成字节流

gcc - 对于 gnu 和 ibm openmp 库,KMP_AFFINITY=verbose 等效吗?

c++ - 在 Visual Studio 2010 中使用 SFML

c - 使用 RDTSC 测量时差 - 结果太大

c - OMP 对于并行线程 ID hello world