2016-10-14 2 views
0

----- пример кода -----------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 для выгрузки кода на GPU. Но производительность снижалась. Я ищу какую-то бумагу, и они делают вывод, что OpenACC не может использовать общую память в GPU. Но я думаю, что основная причина заключается в том, что блокирование/блокировка предотвращают параллель. Потому что обработка данных приводит к зависимости данных. Если OpenACC не дает или не поощряет обработку кода? Если есть соус или пример, что технология обработки тиллинга улучшает код OpenACC.

ответ

1

OpenACC может выполнять автоматическую и явную разбивку (через предложение плитки), однако, я не думаю, что это ваша проблема. Проблема, которую я вижу, заключается в том, что цикл 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; 
    } 

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

Смежные вопросы