使用omp线程的2种并行方式之间的实际差异

时间:2019-03-23 09:47:17

标签: c multithreading ubuntu parallel-processing openmp

我正在尝试使用OMP线程并行化程序。

我正在做的事情如下,它工作得很好:

 #pragma omp parallel num_threads(threadnum) \
default(none) shared(scoreBoard, nDiag, qlength, dlength) private(nEle, i, si, sj, ai, aj, max)
        {
            for (i = 1; i < nDiag; ++i)
            {
                if (i <= qlength && i <= dlength) nEle = i;
                else if(i <= findmax(qlength, dlength)) nEle = findmin(qlength, dlength);
                else nEle = 2*findmin(qlength, dlength) - i + abs(qlength - dlength);
                calcfirstele(%si, %sj);

                #pragma omp for
                for (j = 1; j <= nEle; ++j)
                {
                    ai = si - j + 1;
                    aj = sj + j - 1

                    max = searchmax(ai,aj);
                    scoreBoard[ai][aj] = max;
                }
            }
        }

但是不等于:

        for (i = 1; i < nDiag; ++i)
        {
            if (i <= qlength && i <= dlength) nEle = i;
            else if(i <= findmax(qlength, dlength)) nEle = findmin(qlength, dlength);
            else nEle = 2*findmin(qlength, dlength) - i + abs(qlength - dlength);
            calcfirstele(%si, %sj);
             #pragma omp parallel num_threads(threadnum) \
            default(none) shared(scoreBoard) private(nEle, i, si, sj, ai, aj, max)
            #pragma omp for
            for (j = 1; j <= nEle; ++j)
            {
                ai = si - j + 1;
                aj = sj + j - 1

                max = searchmax(ai,aj);
                scoreBoard[ai][aj] = max;
            }
        }

为什么当我使用第二个程序时,我的程序比串行程序花更多的时间,而在第一种情况下,它比串行程序快得多?无法理解它们之间的区别

1 个答案:

答案 0 :(得分:1)

您的第二个代码错误,并且行为未定义。 这样做的原因是,通过声明nElesisj private,您可以创建这些变量的某些本地(每线程)版本,而无需赋予它们任何值。因此,nEle(即您的for循环的上限)可以具有任何值,可能会大大增加计算时间。

为了修复您的代码,您给出的代码段应如下所示(有一些简化,没有经过明显测试):

for (int i = 1; i < nDiag; ++i) {
    if (i <= qlength && i <= dlength)
        nEle = i;
    else if(i <= findmax(qlength, dlength))
        nEle = findmin(qlength, dlength);
    else
        nEle = 2*findmin(qlength, dlength) - i + abs(qlength - dlength);
    calcfirstele(%si, %sj); // not sure what this suppose to mean...

    #pragma omp parallel for num_threads(threadnum) private(ai, aj, max)
    for (int j = 1; j <= nEle; ++j) {
        ai = si - j + 1;
        aj = sj + j - 1

        max = searchmax(ai,aj);
        scoreBoard[ai][aj] = max;
    }
}