Директивы акселератора не работают

Это код для умножения матриц

 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 мс. Непонятно, как он собрал время.

Спасибо тем, кто пытался помочь. - коврик

Другие вопросы по тегам