【发布时间】:2016-09-13 16:52:02
【问题描述】:
我正在学习如何使用 GNU C 编译器 6.2.1 将 OpenMP 与 C++ 结合使用,并且我测试了以下代码:
#include <stdio.h>
#include <omp.h>
#include <iostream>
int b=10;
int main()
{
int array[8];
std::cout << "Test with #pragma omp simd linear:\n";
#pragma omp simd linear(b)
for (int n=0;n<8;++n) array[n]=b;
for (int n=0;n<8;++n) printf("Iteration %d: %d\n", n, array[n]);
std::cout << "Test with #pragma omp parallel for linear:\n";
#pragma omp parallel for linear(b)
for (int n=0;n<8;++n) array[n]=b;
for (int n=0;n<8;++n) printf("Iteration %d: %d\n", n, array[n]);
}
在这两种情况下,我都希望得到一个从 10 到 17 的数字列表,但事实并非如此。 #pragma omp simd linear(b) 被完全忽略,array 中的每个值只打印 10 个。对于#pragma omp parallel for linear(b),程序输出10,10,12,12,14,14,16,16。
我使用g++ -fopenmp -Wall main.cpp -o main.o 编译文件。我该如何解决这个问题?
编辑:更仔细地阅读规范,我发现linear 子句用获得的最后一个值覆盖了初始值(即,如果我们在第一个循环之后以b=10 开始,我们有b=17)。
但是,如果我将 schedule(dynamic) 添加到并行循环中,程序将正确运行。为什么我必须指定该参数才能正确执行?
【问题讨论】:
-
这很有趣。这可以用 GCC5.4.0 重现,除了 GCC 的 openmp 不接受没有
simd子句的linear子句(测试代码的后半部分不能用 GCC 编译)。为了让 b 在 GCC 上发生变化,我使用#pragma omp parallel for simd linear(b)但在每个线程中, b 仍然是一个固定值。您可以提交错误报告并向 GCC 团队或其他编译器开发组询问。