Разделение разделов внутри параллельной omp для: OpenMP - PullRequest
1 голос
/ 21 апреля 2010

У меня такая ситуация:

#pragma omp parallel for private(i, j, k, val, p, l)

for (i = 0; i < num1; i++)  
    {  
   for (j = 0; j < num2; j++)  
       {
         for (k = 0; k < num3; k++)     
             {  
              val = m[i + j*somenum + k*2]  

              if (val != 0)  
              for (l = start; l <= end; l++)  
                  {  
                    someFunctionThatWritesIntoGlobalArray((i + l), j, k, (someFunctionThatGetsValueFromAnotherArray((i + l), j, k) * val));  
                  }

              }  
         }  

        for (p = 0; p < num4; p++)  
            {  
               m[p] = 0;  
            }    
      }

Спасибо за чтение, фу! Ну, я заметил очень незначительную разницу в результатах (0,999967 [omp] против 1 [серийный]), когда я использую выше (что в 3 раза быстрее) против последовательной реализации. Теперь я знаю, что я делаю ошибку здесь ... особенно очевидна связь между циклами. Можно ли распараллелить это с помощью omp разделов? Я попробовал некоторые варианты, такие как создание shared (p) {делая это, я получил правильные значения, как в последовательной форме}, но тогда ускорения не было.

Любой общий совет по работе с openmp прагмами над множеством циклов for также был бы мне полезен!

1 Ответ

1 голос
/ 21 апреля 2010

Это действительно переформулировка или уточнение вашего предыдущего вопроса, это поможет SOers, если вы отредактировали это, а не задали «новый» вопрос. Все еще ...

Когда вы написали свой код, OpenMP будет разделять итерации вашего самого внешнего цикла, который управляется оператором

for (i = 0; i < num1; i++)

к доступным темам. Таким образом, используя расписание цикла по умолчанию, если у вас есть 4 потока, каждый из них выполнит 1/4 итераций. Это, вероятно, будет означать, что поток 0 выполняет итерации i = 0,1,2,..., а поток 1 выполняет итерации (num1/4)+1, (num1/4)+2,... и так далее. Если вы новичок в программировании OpenMP, вы действительно должны выяснить, как итерации цикла распределяются между потоками для себя. Вы также должны исследовать последствия изменения планирования цикла. Это важная часть изучения параллельного программирования.

Затем OpenMP выполнит внутренние циклы в каждом потоке, поэтому каждый поток будет выполнять циклы, управляемые переменными j,k,l,p. Они больше не будут распараллеливаться, ваша программа не реализует динамическое управление потоками.

Одним из следствий этого является то, что все потоки обновят массив m для всех значений p. Мне это не кажется разумным.

Вы пишете, что есть расхождение между результатами последовательной реализации и параллельной реализации. Но вы не указываете, какой результат отличается. Какая переменная имеет другое значение в конце цикла? В общем случае не следует ожидать точного равенства результатов с плавающей точкой в ​​последовательных и параллельных программах, поскольку важен порядок выполнения арифметики f-p. f-p арифметика не является по-настоящему коммутативной и не является по-настоящему ассоциативной или действительно дистрибутивной. Даже простая операция сложения чисел в общем случае не может быть гарантирована одинаковой для последовательного и параллельного выполнения одной и той же программы.

Однако, не зная, как вычисляется результат, о котором вы сообщаете, совершенно невозможно сказать, почему вы получаете разницу. Это может быть «нормальное» поведение, это может быть ошибка.

...