当我准备一些代码示例以向我的队友介绍 OpenMP 时,我发现了一个奇怪的案例。首先我写了一个经典的循环:
void sequential(int *a, int size, int *b)
{
int i;
for (i = 0; i < size; i++) {
b[i] = a[i] * i;
}
}
for 指令的正确 OpenMP 用法很简单。我们只需要将int i
声明移入范围即可private
。
void parallel_for(int *a, int size, int *b)
{
#pragma omp parallel for
for (int i = 0; i < size; i++) {
b[i] = a[i] * i;
}
}
但是当我编写以下函数时,我预计我会得到与其他 2 个不同的结果,因为int j
我声明的共享超出了 for 循环范围。但是使用我的测试框架,我没有看到我预期的错误,该函数的输出值不正确。
void parallel_for_with_an_usage_error(int *a, int size, int *b)
{
int j;
#pragma omp parallel for
for (int i = 0; i < size; i++) {
/*int*/ j = a[i]; //To be correct j should be declared here, in-loop to be private !
j *= i;
b[i] = j;
}
}
我有一个完整的测试源代码,它使用 VS'12 和 gcc(启用 C++11)构建在这里http://pastebin.com/NJ4L0cbV
你知道编译器是做什么的吗?它是否检测到错误共享,是否int j
由于优化启发式而在循环中移动?
谢谢