C++ 并行化时的不同答案 #pragma omp parallel for 对于(int i=0;i

C++ 并行化时的不同答案 #pragma omp parallel for 对于(int i=0;i,c++,parallel-processing,openmp,C++,Parallel Processing,Openmp,您有多个线程写入Output[j]。这会导致争用条件。一个线程写入的值被另一个具有不同值的线程替换。您有多个线程写入Output[j]。这会导致争用条件。一个线程写入的值会被另一个具有不同值的线程替换。问题在于内部循环具有写入争用条件,因此,例如,以下两条语句可能并行发生: #pragma omp parallel for for (int i = 0; i <500; i++) for (j=i; j < 102342; j++) { Output

您有多个线程写入
Output[j]
。这会导致争用条件。一个线程写入的值被另一个具有不同值的线程替换。

您有多个线程写入
Output[j]
。这会导致争用条件。一个线程写入的值会被另一个具有不同值的线程替换。

问题在于内部循环具有写入争用条件,因此,例如,以下两条语句可能并行发生:

#pragma omp parallel for    
for (int i = 0; i <500; i++)
   for (j=i; j < 102342; j++)
    {
      Output[j] += staticConstant[i] * data[j-i];
    }
}
每一行的代码归结为:

Output[42] = Output[42] + staticConstant[9] * data[42-9];
Output[42] = Output[42] + staticConstant[19] * data[42-19];
但是,并行器可能会导致代码如下运行:

Load O[42] to R1
Load C[] to R2
Add R2 to R1
Store R1 to O[42]
正如您可能看到的,两条
Load O[42]
行在添加
C[9]
C[19]
之前加载值,因此实际上忽略了第一次计算

最简单的修复方法是:

Load O[42] to R1
Load O[42] to R3
Load C[9] to R2
Load C[19] to R4
Add R2 to R1
Add R4 to R3
Store R1 to O[42]
Store R3 to O[42]

for(int i=0;i问题在于您的内部循环具有写竞争条件,因此,例如,以下两条语句可能并行发生:

#pragma omp parallel for    
for (int i = 0; i <500; i++)
   for (j=i; j < 102342; j++)
    {
      Output[j] += staticConstant[i] * data[j-i];
    }
}
每一行的代码归结为:

Output[42] = Output[42] + staticConstant[9] * data[42-9];
Output[42] = Output[42] + staticConstant[19] * data[42-19];
但是,并行器可能会导致代码如下运行:

Load O[42] to R1
Load C[] to R2
Add R2 to R1
Store R1 to O[42]
正如您可能看到的,两条
Load O[42]
行在添加
C[9]
C[19]
之前加载值,因此实际上忽略了第一次计算

最简单的修复方法是:

Load O[42] to R1
Load O[42] to R3
Load C[9] to R2
Load C[19] to R4
Add R2 to R1
Add R4 to R3
Store R1 to O[42]
Store R3 to O[42]

for(int i=0;我感谢!另一个选项是交换两个循环。
j
循环有更多的迭代,因此并行化最外层循环会减少开销。感谢!另一个选项是交换两个循环。
j
循环有更多的迭代,因此并行化最外层循环会减少开销。