Разделение разделов внутри параллели omp для: OpenMP

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

#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[serial]), когда я использую вышеуказанное (что в 3 раза быстрее) по сравнению с последовательной реализацией. Теперь я знаю, что делаю здесь ошибку... особенно очевидна связь между петлями. Можно ли распараллелить это, используя разделы omp? Я пробовал некоторые варианты, например, сделать shared(p) {сделав это, я получил правильные значения, как в последовательной форме}, но тогда никакого ускорения не было.

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


person Sayan Ghosh    schedule 21.04.2010    source источник
comment
это довольно трудно читать. Что это делает? Какое-то тензорное сокращение? Вы можете дать математическую формулу?   -  person Anycorn    schedule 21.04.2010
comment
Ну, это часть программы, которая выполняет линейно разделимую свертку ядра. Я бы отредактировал его, чтобы он выглядел лучше.   -  person Sayan Ghosh    schedule 21.04.2010
comment
какая цель m ? Ваша функция изменяет его? самая внутренняя функция когда-либо записывает в одну и ту же ячейку памяти? недостаточно информации, чтобы сделать осмысленное предложение. Вам необходимо определить возможные условия гонки.   -  person Anycorn    schedule 21.04.2010


Ответы (1)


Это действительно повторение или уточнение вашего предыдущего вопроса, это помогло бы 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 арифметика не является ни истинно коммутативной, ни истинно ассоциативной, ни истинно дистрибутивной. Даже простая операция сложения чисел в общем случае не может быть гарантированно одинаковой для последовательного и параллельного выполнения одной и той же программы.

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

person High Performance Mark    schedule 21.04.2010
comment
Прошу прощения за ляпы и создание отдельной темы. Программа довольно большая, и я имею дело только с частью, и я согласен, что потерял конкретику, пытаясь упростить ее. Но я считаю, что ваше описание дает мне достаточно подсказок, чтобы начать углубляться в программу (и OpenMP), поскольку у меня действительно нет полного понимания поведения кода в отношении OpenMP. Спасибо Саян - person Sayan Ghosh; 21.04.2010
comment
Как вы сказали --- Одним из следствий этого является то, что все потоки будут обновлять массив m для всех значений p. Мне это не кажется разумным. Я приложил раздел с #pragma omp Critical, из-за чего время работы программы почти приблизилось к серийной версии. - person Sayan Ghosh; 22.04.2010