openacc и обработка кэша

#optimization #blocking #openacc

#оптимизация #блокировка #openacc

Вопрос:

—— пример кода ————

 for (body1 = 0; body1 < NBODIES; body1   ) {
   for (body2=0; body2 < NBODIES; body2  ) {
     OUT[body1]  = compute(body1, body2);
   }
}
 

—— блокирующий код——

 for (body2 = 0; body2 < NBODIES; body2  = BLOCK) {
   for (body1=0; body1 < NBODIES; body1   ) {
      for (body22=0; body22 < BLOCK; body22   ) {
         OUT[body1]  = compute(body1, body2   body22);
      }
   }
}
 

Я вставляю директивы OpenACC для выгрузки кода на графический процессор.
Но производительность снижалась.
Я ищу какую-то статью, и они приходят к выводу, что причина в том, что OpenACC не может использовать общую память в GPU. Но я думаю, что основная причина в том, что обработка / блокировка предотвращают параллелизм. Потому что обработка приводит к зависимости от данных.
Если OpenACC не предоставляет или не поощряет обработку кода?
Если есть решение или пример, что технология обработки улучшает код OpenACC.

Ответ №1:

OpenACC может выполнять автоматическое и явное разбиение на листы (с помощью предложения tile) однако я не думаю, что это ваша проблема. Проблема, которую я вижу, заключается в том, что цикл body2 не может быть распараллелен из-за зависимости от «OUT [body1]». OpenACC может выполнять скалярные сокращения параллельно, поэтому вы можете попробовать следующее:

   #pragma acc parallel loop 
  for (body1 = 0; body1 < NBODIES; body1   ) {
    sum = 0.0;
  #pragma acc loop reduction( :sum)
    for (body2=0; body2 < NBODIES; body2  ) {
      sum  = compute(body1, body2);
    }
    OUT[body1]  = sum;
  }
 

Конечно, я предполагаю, что здесь так, если это не поможет, пожалуйста, опубликуйте соответствующий пример проблемы. Если вы используете PGI, пожалуйста, также отправляйте сообщения об отзывах компилятора (-Minfo=accel ).