C++ Openmp程序在没有关键部分的情况下工作

C++ Openmp程序在没有关键部分的情况下工作,c++,parallel-processing,openmp,C++,Parallel Processing,Openmp,在Openmp讲座中,类似的代码显示为Openmp中的竞争条件。在for循环中,sum+=不在临界部分,因此线程的执行顺序会改变结果 但在我的程序中并非如此。无论我多久运行一次这个程序,总和总是打印为285(1²+2²+3²+4²+5²+6²+7²+8²+9²)。在我的程序中似乎根本没有任何比赛条件 int main() { int sum = 0; int a[10]; int b[10]; for (int count

在Openmp讲座中,类似的代码显示为Openmp中的竞争条件。在for循环中,sum+=不在临界部分,因此线程的执行顺序会改变结果

但在我的程序中并非如此。无论我多久运行一次这个程序,总和总是打印为285(1²+2²+3²+4²+5²+6²+7²+8²+9²)。在我的程序中似乎根本没有任何比赛条件

 int main()
    {
        int sum = 0;
        int a[10];
        int b[10];
        for (int counter = 0; counter < 10; counter++) {
            a[counter] = counter;
            b[counter] = counter;
        }


#pragma omp parallel for shared(sum)
    for (int i = 0; i < 10; i++) {
        sum += a[i] * b[i];  
    }
    cout << "sum is " << sum; // always prints 285
    std::cin.get();
    return 0;
}
intmain()
{
整数和=0;
INTA[10];
int b[10];
用于(整数计数器=0;计数器<10;计数器++){
a[计数器]=计数器;
b[计数器]=计数器;
}
#用于共享的pragma omp并行(总和)
对于(int i=0;i<10;i++){
总和+=a[i]*b[i];
}

cout仅仅因为它不会在您的机器上显示错误的行为,并且您的编译器选项并不意味着没有bug

不同的编译器、不同的优化选项或不同的硬件很可能会暴露该缺陷

竞争条件是棘手的,因为在许多情况下或许多配置中,它们通常不会真正表现为问题(除非在您的最大客户的生产中数月后深夜出现问题)。 竞态条件仍然是bug和未定义的行为(这意味着您的编译器可以假设它们不存在,并且可能实际使用该假设,并因此微妙地错误编译程序的其他部分)


事实上,当多个线程正在修改同一个变量(或者一些线程正在修改,一些线程正在读取)时,您需要同步对共享变量的访问—始终—以实现无争用。

仅仅因为它不会在您的机器上显示错误行为,并且您的编译器选项并不意味着没有错误

不同的编译器、不同的优化选项或不同的硬件很可能会暴露该缺陷

竞争条件是棘手的,因为在许多情况下或许多配置中,它们通常不会真正表现为问题(除非在您的最大客户的生产中数月后深夜出现问题)。 竞态条件仍然是bug和未定义的行为(这意味着您的编译器可以假设它们不存在,并且可能实际使用该假设,并因此微妙地错误编译程序的其他部分)


事实上,当多个线程修改同一个变量时(或者有些线程正在修改,有些线程正在读取),您需要同步对共享变量的访问-始终-以避免竞争。

仅仅因为它不会在您的计算机上显示错误行为,并且您的编译器选项并不意味着没有错误。不同的编译器、不同的优化选项或不同的硬件可能会暴露错误。Jesper的评论是回答正确。如果您想知道竞态条件不影响系统结果的具体原因,则必须在问题中包括编译器版本、编译标志和特定的系统配置。编译器可以查看循环计数,发现并行化是无效的。@ForceBru竞态条件也是一个问题如果不使用同步,变量的读取器可能会看到该变量处于部分更改的状态。@ForceBru
sum
可能会在一个线程中特别更新,然后另一个线程写入该变量,然后第一个线程完成写入,导致最后一个不正确的值
sum
使用编译器和编译器选项不会在计算机上显示错误行为并不意味着没有错误。不同的编译器、不同的优化选项或不同的硬件可能会暴露错误。Jesper的评论是正确的答案。如果您想知道竞态条件不影响计算机上的结果的具体原因您的系统。问题中必须包括您的编译器版本、编译标志和特定的系统配置。编译器可能会查看循环计数,并发现并行化是无效的。@ForceBru竞争条件还涉及一个事实,即如果没有同步,变量的读取器可能会看到该变量处于部分更改的状态使用了异常。@ForceBru
sum
可能特别在一个线程中更新,然后另一个线程写入,然后第一个线程完成写入,导致最后一个不正确的值
sum