Директивы акселератора не работают
Это код для умножения матриц
program ex
implicit none
real :: a(256,256),b(256,256),c(256,256),t1,t2
integer i,j,k,sum
sum=0
do j = 1,256
do i = 1,256
a(i,j) = 1
b(i,j) = 1
c(i,j) = 0.0
enddo
enddo
call cpu_time(t1)
!$acc region do
do i=1,256
do j=1,256
sum=0
do k=1,256
sum=sum+a(i,k)*b(k,j)
c(i,j)=sum
end do
end do
end do
!$acc end region
call cpu_time(t2)
print*,"cpu time=",t2-t1
print*,c
end program ex
Когда я выполняю это, время выполнения составляет 75 мсек при использовании директив акселератора и компилятора PGI. Но когда я запускаю то же матричное умножение с реализацией "cuda fortran", время выполнения составляет всего 5 мсек. Так что есть большая разница, хотя я использовал директивы акселератора. Поэтому я сомневаюсь, что мои директивы акселератора работают правильно.
2 ответа
Я попытался ускорить вашу программу, используя очень похожие директивы акселератора OpenHMPP. Обратите внимание, что я переключил одну вашу строку, которая, вероятно, ошибочно находится в самом внутреннем цикле. Также обратите внимание, что я должен был сообщить компилятору о происходящем сокращении. Также я переименовал переменную сокращения, потому что она затеняла sum
внутренняя функция.
Производительность не очень хорошая из-за перегрузки при запуске ядра графического процессора и из-за передачи памяти. Вам нужно на порядок больше работы, чтобы использовать GPU было выгодно.
Например, когда я использовал матрицы 2000 x 2000, тогда время выполнения CPU составляло 41 секунду, а время выполнения GPU - только 8 с.
program ex
implicit none
real :: a(256,256),b(256,256),c(256,256),t1,t2
integer i,j,k,sm
sm=0
do j = 1,256
do i = 1,256
a(i,j) = 1
b(i,j) = 1
c(i,j) = 0.0
enddo
enddo
call cpu_time(t1)
!$hmpp region, target = CUDA
!$hmppcg gridify, reduce(+:sm)
do i=1,256
do j=1,256
sm=0
do k=1,256
sm=sm+a(i,k)*b(k,j)
end do
c(i,j)=sm
end do
end do
!$hmpp endregion
call cpu_time(t2)
print*,"cpu time=",t2-t1
print*,sum(c)
end program ex
редактировать: это было бы, вероятно, не использовать reduce(+:sm)
, но просто private(sm)
К вашему сведению, ОП также разместил этот вопрос на форуме пользователей PGI (http://www.pgroup.com/userforum/viewtopic.php?t=3081). Мы считаем, что первоначальная проблема была результатом ошибки пилота. Когда мы профилировали его код с использованием CUDA Prof, время выполнения ядра CUDA Fortran составляло 205 мс против 344 мс с использованием модели PGI Accelerator. Кроме того, если я исправлю его код так, чтобы "c(i,j)=sum" помещался за пределы внутреннего цикла "k", время модели PGI Accelerator Model сократилось до 123 мс. Непонятно, как он собрал время.
Спасибо тем, кто пытался помочь. - коврик