OpenMP min reduction and std::min
OpenMP min reduction and std::min
我正在测试OpenMP最小减少。如果我像下面这样编写代码,它将返回正确的结果:res = 3.
#include <omp.h>
#include <iostream>
#include <algorithm>
int main(){
omp_set_num_threads(5);
float res=10;
#pragma omp parallel for default(shared) reduction(min:res)
for(int i1 = 0; i1 <= 10; i1++)
for(int i0 = 0; i0 <= 10; i0++)
if(res > 3.0+i1+20*i0)
res = 3.0+i1+20*i0;
std::cout << "res = " << res << std::endl;
return 0;
}
但是如果我以另一种方式编写,将" If "语句替换为"std::min",那么结果是错误的:res = 10.
#include <omp.h>
#include <iostream>
#include <algorithm>
int main(){
omp_set_num_threads(5);
float res=10;
#pragma omp parallel for default(shared) reduction(min:res)
for(int i1 = 0; i1 <= 10; i1++)
for(int i0 = 0; i0 <= 10; i0++)
res = std::min(res,static_cast<float>(3.0+i1+20*i0));
std::cout << "res = " << res << std::endl;
return 0;
}
是否OpenMP min降低干扰std::min?
首先,你的代码是符合标准的:不管你在并行语句中使用哪种类型的代码。
reduction
子句意味着每个线程都有自己的私有副本,初始化为min
操作符的中性元素(即约简项类型中最大的可表示数),并且它们将一直使用它直到构造结束。此时,这些私有副本将使用还原标识符(在您的示例中是min
操作符)还原为原始列表项。所以这里没有竞争条件
我已经使用与您相同的版本执行了您的代码,它工作得很好:icpc (ICC) 16.0.0
和OpenMP版本201307
。这个问题是否与您正在使用的c++标准头文件有关?
我会在得出结论之前交换循环。在类似的情况下,我发现需要单独的内部和外部循环缩减变量。-std::min适用于icpc,但不适用于g++或msvc
问题是你有数据竞赛。
在您的第一个示例中,所有线程中的最小值由OpenMP运行时计算:每个线程获得自己的res
,运行时确定最小值。运行时确保res
被所有线程正确读写。
在第二个示例中,每个线程调用std::min
来确定res
和另一个值之间的最小值。res
是shared
,因为你的default(shared)
子句,所以所有的线程将试图同时使用和更新res
,这是一个数据竞争。
您应该继续使用第一个示例。如果您想使用std::min
,您必须使用锁或类似的东西来防止数据竞争。
相关文章:
- 如何使用std::min和std::less返回对象
- 关于 std::min, std::max 中的比较运算符的混淆
- 使用 CImg 库的 std::min 和 std::max 的编译问题
- 第 5 行:字符 54:错误:调用"min(int,std::__cxx11::basic_string<char>::size_type)"没有匹配函数
- 如何使用函数std::min()来计算最小值
- 将迭代器值与 std::min 一起固定到 end()
- C++是否在 std::min 和 std::max 下标准化 std::optional 的行为?
- c++ 中 std::min 的效率
- std :: min-设计考虑
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 使用`std :: min`作为算法参数
- std::min 与参数包
- 执行 std::min(0.0, 1.0) 和 std::max(0.0, 1.0) 会产生未定义的行为
- 什么时候会: std::abs(x -y) < std::numeric_limits:<double>:min()
- 为什么挥发性不使用std :: min编译
- 不知道为什么"std::min"功能CPP有任何问题
- 为什么 std::min(std::initializer_list<T>) 按值接受参数?
- 有没有办法防止开发人员使用std::min, std::max
- 写std::min/std::max对于异构宽度的int
- std::min/std::max作为模板比较器