#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 ).