【发布时间】:2017-01-16 13:05:41
【问题描述】:
我正在测试 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;
}
但是如果我用“std::min”替换“if”语句以另一种方式编写,那么结果是错误的: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:应该从 OpenMP 3.1 开始工作。另一个有趣的问题是它是否适用于fmin。我想我在手册中看到了一个例子。fmin和std::min不是一回事,尽管有些人是这么想的。 -
在阅读了更多标准之后,明确提到
min应该像这样实现out=in<out?in:out;也许在你的系统上std:min()不遵守这个......跨度> -
OpenMP 3.1 手册在第 266 页上给出了一个使用
fmaxf的示例,所以我认为它也适用于fmin和fmax。我虽然std::min扩展到三元运算符,所以我不确定它为什么会失败。您将不得不查看宏。 -
here 我解释了为什么 std::min 和 fmin 不一样。
-
std::min可以通过多种不同的方式实现en.cppreference.com/w/cpp/algorithm/min。您可以做的是使用 OpenMP4.0 创建一个自定义 Reduction 运算符,该运算符将与std::min一起使用。