代码2的问题在于,由于存在并行区域(这非常明显),无法更新delE。但是,代码1达不到要求,并显示出模棱两可的结果。如果有任何人可以提供正确的解决方案以并行运行代码1或代码2,我将有义务。
此处grad_compute返回一个2d指针,每个并行循环都需要存储或添加该2d指针。 norm_delE和delE分别声明为3d和2d指针。
#pragma omp parallel for num_threads(8)
for (int k = 0; k < no_of_sources; k++)
{
double** gnorm = grad_compute(/*parameters*/);
// code 1
/* for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++)
{
norm_delE[i][j][k] = gnorm[i][j]; } } */
// code 2
/* for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++)
{ delE[i][j] += gnorm[i][j]; } } */
}
如果您需要更多信息,我们将不胜感激。
最佳答案
编辑和更新:
对于代码1,无需使用gnorm,而grad_compute的结果直接分配给norm_delE,但norm_delE的尺寸应更改为[no_of_sources] * [rows] * [cols]。
对于code2,因为同时有多个线程写入delE数组,所以应限制每个线程仅更新某些行
因此我们为代码1创建2个omp,为代码2创建另一个omp
另外,尽管对于内存管理,建议使用std::vector或unique_ptr,但grad_compute所获取的内存应由free_memory之类的函数释放。
#pragma omp parallel num_threads(8)
{
//code 1
#pragma omp for
for (int k = 0; k < no_of_sources; k++)
{
norm_delEk[k] = grad_compute(/*parameters*/);
}
//code 2
#pragma omp for
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
for (int k = 0; k < no_of_sources; k++)
{
delE[i][j] += norm_delE[k][i][j];
}
}
}
}
//memory that acquired should be released
free_memory(norm_delE);