代码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);

09-06 00:41