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。)
答案 0 :(得分:4)
C ++的OpenMP规范不支持原子最小值。 C ++ 11也没有。
我假设在你的算法中,x
可以计算任何有效的索引,无论线程如何。
我建议更改你的算法,这样每个线程都使用自己的val
数组,然后在最后进行最终的协调,也可以通过索引进行并行化。这将完全避免锁和原子,并为您提供分离每个线程的数据的好处,即没有机会进行虚假缓存共享。换句话说,它应该更快。