c++ - 编译器是否检测到错误的共享变量?

标签 c++ c++11 openmp

当我准备一些代码示例以向我的队友演示 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;
    }
}

但是当我编写以下函数时,由于共享 int j,我预计我会得到与其他 2 个不同的结果,我声明了 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

感谢

最佳答案

在我看来,可能发生的情况是编译器正在进行一些优化。由于在上面粘贴的代码(没有 cout)中,变量 j 不在循环内以外的任何地方,编译器可以在生成的汇编代码中将 j 的声明放在循环内。

另一种可能性是编译器可能将循环内的 3 条语句转换为一条语句,即 from

/*int*/ j = a[i]; //To be correct j should be declared here, in-loop to be private !
j *= i;
b[i] = j;

到,

b[i] = a[i] * i;

无论它是否是 OpenMP 代码,编译器都会进行此优化。

关于c++ - 编译器是否检测到错误的共享变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18024847/

相关文章:

parallel-processing - 基于求和的 OpenMP

c - block 错误的openmp

c++ - 如何从 8 位整数中获得大于 8 位的值?

c++ - boolean 变量没有初始化就有值?

c++ - 如何使用 Qt 将参数从 QML View 发送到模型?

c++ - 是否泄漏 std::thread 未定义行为?

UML 中的 C++11 可变模板参数表示法

c++ - 哪种是产生线程的最佳方法?

c++ - Qt:使用 QGraphicsscene 显示图像的问题

c++ - 为什么 std::chrono 在测量 OpenMP 并行化 for 循环和编译器优化的执行时间时不起作用?