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
循环有更多的迭代,因此并行化最外层循环会减少开销。