RL-*_*L-S 1 c++ multithreading g++ openmp c++11
我想在循环parallel外部的区域中使用 OpenMP 缩减for。根据OpenMP 参考parallel,可以在区域中使用归约子句,因此不需要for循环 or 。sections
reduction (min:...)但是,当在某个区域使用 OpenMP 时parallel,我得到的结果不正确。但是,如果我对 a 使用完全相同的结构reduction (max:...),则结果是正确的。如果我使用循环进行最小减少(#pragma omp for reduction (min:...)),结果是正确的,但我认为这没有必要。这是我的代码:
#include <omp.h>
#include <iostream>
#include <limits>
#include <algorithm>
int main(){
auto minVar { std::numeric_limits<int>::max() };
auto maxVar { std::numeric_limits<int>::min() };
auto minVarLoop { std::numeric_limits<int>::max() };
#pragma omp parallel
{
int threadNo { omp_get_thread_num() };
#pragma omp reduction (min:minVar)
minVar = std::min(minVar, threadNo);
// minVar = minVar < threadNo ? minVar : threadNo; // also doesn't work
#pragma omp for reduction(min:minVarLoop)
for (int i=0; i<omp_get_num_threads(); ++i){
minVarLoop = std::min(minVarLoop, threadNo);
}
#pragma omp reduction (max:maxVar)
maxVar = std::max(maxVar, threadNo);
}
std::cout
<< "min thread num: " << minVar
<< "\nmax thread num: " << maxVar
<< "\nmin thread num from Loop: " << minVarLoop
<< "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
16 个线程的预期输出是
min thread num: 0
max thread num: 15
min thread num from Loop: 0
Run Code Online (Sandbox Code Playgroud)
我得到的输出是
min thread num: 12 // or any other number between 0 and 15
max thread num: 15
min thread num from Loop: 0
Run Code Online (Sandbox Code Playgroud)
我正在 Ubuntu 21.04 上使用 g++ 版本 10.3.0 进行编译,仅使用标志-fopenmp。
我在忽略什么?
编辑:不初始化minVar,即使用int minVar;某种方式使其工作,但我没有找到令人满意的解决方案。此外,尝试与 相同maxVar,会使这些结果不正确。天啊。
您正在使用编译器尚不支持的功能。如果您编译代码,-Wall您将看到 GCC 10.3.0 显示此警告:
red.cc:15: warning: ignoring \xe2\x80\x98#pragma omp reduction\xe2\x80\x99 [-Wunknown-pragmas]\n 15 | #pragma omp reduction (min:minVar)\n |\nred.cc:24: warning: ignoring \xe2\x80\x98#pragma omp reduction\xe2\x80\x99 [-Wunknown-pragmas]\n 24 | #pragma omp reduction (max:maxVar)\n |\nRun Code Online (Sandbox Code Playgroud)\n如果您更正代码,就像我在下面显示的那样使用正确的拼写(请参阅scope Construct),编译器仍然会反对,因为它还不支持 OpenMP API 5.1 版本:
\nred.cc:15: warning: ignoring \xe2\x80\x98#pragma omp scope\xe2\x80\x99 [-Wunknown-pragmas]\n 15 | #pragma omp scope reduction (min:minVar)\n |\nred.cc:24: warning: ignoring \xe2\x80\x98#pragma omp scope\xe2\x80\x99 [-Wunknown-pragmas]\n 24 | #pragma omp scope reduction (max:maxVar)\n |\nRun Code Online (Sandbox Code Playgroud)\n正确的拼写如下:
\n#include <omp.h>\n#include <iostream>\n#include <limits>\n#include <algorithm>\n\nint main(){\n auto minVar { std::numeric_limits<int>::max() };\n auto maxVar { std::numeric_limits<int>::min() };\n auto minVarLoop { std::numeric_limits<int>::max() };\n\n #pragma omp parallel\n {\n int threadNo { omp_get_thread_num() };\n\n #pragma omp scope reduction (min:minVar)\n minVar = std::min(minVar, threadNo);\n // minVar = minVar < threadNo ? minVar : threadNo; // also doesn\'t work\n \n #pragma omp for reduction(min:minVarLoop)\n for (int i=0; i<omp_get_num_threads(); ++i){\n minVarLoop = std::min(minVarLoop, threadNo);\n }\n \n #pragma omp scope reduction (max:maxVar)\n maxVar = std::max(maxVar, threadNo);\n }\n std::cout\n << "min thread num: " << minVar\n << "\\nmax thread num: " << maxVar\n << "\\nmin thread num from Loop: " << minVarLoop\n << "\\n";\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n不同的结果是由于竞争条件造成的。不要问为什么你会得到正确的 max 结果,我运行代码时确实会随时得到不同的结果。
\n代码的另一个正确版本(不需要 OpenMP API 5.1 版本的前沿支持)是这样的:
\n#include <omp.h>\n#include <iostream>\n#include <limits>\n#include <algorithm>\n\nint main(){\n auto minVar { std::numeric_limits<int>::max() };\n auto maxVar { std::numeric_limits<int>::min() };\n auto minVarLoop { std::numeric_limits<int>::max() };\n\n #pragma omp parallel reduction(min:minVar) reduction(max:maxVar)\n {\n int threadNo { omp_get_thread_num() };\n\n minVar = std::min(minVar, threadNo);\n\n #pragma omp for reduction(min:minVarLoop)\n for (int i=0; i<omp_get_num_threads(); ++i){\n minVarLoop = std::min(minVarLoop, threadNo);\n }\n\n maxVar = std::max(maxVar, threadNo);\n }\n std::cout\n << "min thread num: " << minVar\n << "\\nmax thread num: " << maxVar\n << "\\nmin thread num from Loop: " << minVarLoop\n << "\\n";\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
300 次 |
| 最近记录: |