如何使一个线程等待使用OpenMP线程完成?

时间:2019-03-11 13:40:21

标签: multithreading ubuntu parallel-processing openmp

我想进行以下填充A矩阵的并行循环。对于每个计算的A [i] [j]元素,我希望A [i-1] [j],A [i-1] [j -1]和A [i0] [j-1]中的价格为先计算出来。因此,我的线程必须等待这些位置的线程计算出它们的结果。我试图做到这一点:

 #pragma omp parallel for num_threads(threadcnt) \
            default(none) shared(A, lenx, leny) private(j)
            for (i=1; i<lenx; i++)
            {   
                for (j=1; j<leny; j++)
                {
                    do
                    {

                    } while (A[i-1][j-1] == -1 || A[i-1][j] == -1 || A[i][j-1] == -1);

                    A[i][j] = max(A[i-1][j-1]+1,A[i-1][j]-1, A[i][j-1] -1);

                }
            }

我的A矩阵以-1初始化,因此,如果A [] []等于-1,则此单元格中的操作未完成。不过,它比串行程序要花费更多的时间。.有什么想法可以避免while循环吗?

1 个答案:

答案 0 :(得分:1)

等待循环似乎不理想。除了燃烧等待旋转的内核外,您还需要大量适当放置的flush指令才能使此代码正常工作。

一种选择,尤其是在更通用的并行化方案中,将使用任务和任务依赖关系来建模不同数组元素之间的依赖关系:

#pragma omp parallel
#pragma omp single
for (i=1; i<lenx; i++) {
    for (j=1; j<leny; j++) {
#pragma omp task depend(in:A[i-1][j-1],A[i-1][j],A[i][j-1]) depend(out:A[i][j])
        A[i][j] = max(A[i-1][j-1]+1,A[i-1][j]-1, A[i][j-1] -1);
    }
}

您可能想考虑阻止矩阵更新,以便每个任务都收到一个矩阵块而不是单个元素,但是总体思路将保持不变。

另一种有用的OpenMP功能可能是ordered构造,它能够完全遵守这种数据依赖关系:

#pragma omp parallel for
for (int i=1; i<lenx; i++) {
    for (int j=1; j<leny; j++) {
#pragma omp ordered depend(source)
#pragma omp ordered depend(sink:i-1,j-1)        
        A[i][j] = max(A[i-1][j-1]+1,A[i-1][j]-1, A[i][j-1] -1);
    }
}

PS:上面的代码未经测试,但应该可以理解。