1

我正在使用 OpenMP 目标卸载将一些嵌套循环卸载到 gpu。我正在使用nowait它来异步调整它。这使它成为一项任务。使用相同的输入值,结果与未卸载时的结果不同(例如,cpu: sum=0.99, offloading sum=0.5)。删除该nowait子句时,它工作得很好。所以我认为问题在于它变成了一项 OpenMP 任务,而我正在努力让它正确。

#pragma omp target teams distribute parallel for reduction( +: sum) collapse(2) nowait depend(in: a, b) depend(out: sum)
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {   
            double c = 0;
            
            for (int k = 0; k < n; k++)
            {
                c += /* some computation */
            }
            
            sum += fabs(c); 
        }
    }
4

1 回答 1

3

OpenMP 5.2 规范指出:

target构造生成一个目标任务。生成的任务区域包围了目标区域。如果存在depend子句,则它与目标任务相关联。[...]。如果nowait存在该子句,则可以推迟目标任务的执行。如果该nowait子句不存在,则目标任务包含的任务

这意味着您的代码在可能延迟执行的任务中执行(带有)。因此,在最坏的情况下,它可以在并行结束时执行,但总是在等待目标任务(或包括类似行为的那些)的所有依赖任务和指令之前执行。因此,您无需在此时间跨度内修改工作数组(也不释放它们)。如果这样做,则行为未定义。nowaittaskwaittaskgroup

您应该特别注意代码中同步点任务依赖关系的正确性(我们无法用当前提供的不完整代码来检查)。

于 2022-02-13T19:22:11.397 回答