OpenMP - параллельный запуск вещей, а некоторые - поочередно внутри них

У меня есть такой сценарий:

for (i = 0; i < n; i++)  
{  
  for (j = 0; j < m; j++)  
{  
  for (k = 0; k < x; k++)  
  {  
     val = 2*i + j + 4*k  
     if (val != 0)  
     {  
      for(t = 0; t < l; t++)  
         {  
           someFunction((i + t) + someFunction(j + t) + k*t)  
         }  
      }  
   }  
}  
}

Учитывая, что это блок A, теперь у меня есть еще два похожих блока в моем коде. Я хочу разместить их параллельно, поэтому я использовал прагмы OpenMP. Однако я не могу распараллелить это, потому что я немного запутался в том, какие переменные будут общими и частными в этом случае. Если бы вызов функции во внутреннем цикле был операцией типа sum + = x, то я мог бы добавить предложение сокращения. В общем, как можно подойти к распараллеливанию кода с помощью OpenMP, когда у нас есть вложенный цикл for, а затем другой внутренний цикл for, выполняющий основную операцию. Я попытался объявить параллельную область, а затем просто поставить прагму for перед блоками, но определенно мне не хватает точки!

Спасибо, Саян


person Sayan Ghosh    schedule 19.04.2010    source источник


Ответы (2)


Я больше программист на Fortran, чем на C, поэтому я плохо знаю OpenMP в стиле C, и я оставлю синтаксис вам.

Ваш самый простой подход здесь, вероятно (я уточню это позже), чтобы просто распараллелить самый внешний цикл. По умолчанию OpenMP будет рассматривать переменную i как частную, а все остальные как общие. Вероятно, это не то, что вам нужно, вы, вероятно, захотите также сделать j, k и t приватными. Я подозреваю, что вы тоже хотите val приватность.

Я немного озадачен утверждением в нижней части вашего набора циклов (например, someFunction...), который, похоже, вообще не возвращает никакого значения. Есть ли побочные эффекты?

Таким образом, вам не нужно объявлять параллельную область, охватывающую весь этот код, и вам, вероятно, следует распараллелить только самый внешний цикл. Если бы вы также распараллелили внутренние циклы, вы могли бы обнаружить, что ваша установка OpenMP либо игнорирует их, порождает больше процессов, чем у вас есть процессоров, либо горько жалуется.

Я говорю, что ваш самый простой подход - это, вероятно, распараллелить самый внешний цикл, потому что я сделал некоторые предположения о том, что делает ваша программа (фрагмент). Если предположения неверны, вы можете распараллелить один из внутренних циклов. Еще один момент, который следует проверить, - это то, что количество выполнений цикла (ов), которые вы распараллеливаете, намного больше, чем количество используемых вами потоков. Вы не хотите иметь циклы выполнения OpenMP с числом отключений, скажем, 7, на 4 потоках, баланс нагрузки будет очень плохим.

person High Performance Mark    schedule 19.04.2010

Вы правы, самым внутренним утверждением будет скорее someFunction ((i + t) + someFunction2 (j + t) + k * t).

person Sayan Ghosh    schedule 19.04.2010
comment
Собственно то, что записывает в массив. Идея состоит в том, что существует большой массив, в котором позиция x, y записывается со значением x ', y' (какое-то другое местоположение массива, уже обновленное OR 0), умноженное на некоторое число. Программа не была написана с учетом параллелизма, так что, знаете ли! Спасибо. - person Sayan Ghosh; 21.04.2010