Фактическое различие между двумя способами равного параллелизма с использованием потоков omp - PullRequest
0 голосов
/ 23 марта 2019

Я пытаюсь распараллелить мою программу, используя потоки 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 Ответ

1 голос
/ 24 марта 2019

Ваш второй код неверен и имеет неопределенное поведение. Причина этого в том, что, объявляя nEle, si и sj 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;
    }
}
...