2012-03-20 3 views
0

Это код для матричного умножениядирективы ускоритель не работает

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

+0

И ваш вопрос? – talonmies

+1

Неужели я глуп, или OP указывает, что время выполнения сократилось с 75 мсек до 5 мсек при использовании директив ускорителя? –

+0

@HighPerformanceMark: CUDA fortran * может * ссылаться на компилятор кода устройства Fortran PGI, а не на ускоритель PGI, но кто мог сказать? – talonmies

ответ

1

Я попытался ускорить вашу программу, используя очень похожие директивы ускорителя OpenHMPP. Обратите внимание, что я переключил одну вашу линию, что, вероятно, ошибочно в самом внутреннем цикле. Также обратите внимание, что мне пришлось советовать составителю сокращения. Также я переименовал редукционную переменную, поскольку она затеняла внутреннюю функцию sum.

Производительность не очень хорошая, из-за перегрузки с запуском ядра GPU и из-за передачи памяти. Вам нужны порядки больше работы для того, чтобы выгодно использовать графический процессор.

Например, когда я использовал матрицы 2000 x 2000, время выполнения процессора составляло 41 секунду, но время выполнения графического процессора всего 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)

0

FYI, ОП также отвечал на этот вопрос на форуме пользователей PGI (http://www.pgroup.com/userforum /viewtopic.php?t=3081). Мы считаем, что исходная проблема была результатом ошибки пилота. Когда мы профилировали его код с использованием CUDA Prof, время выполнения ядра CUDA Fortran составляло 205 мс против 344 мс с использованием модели ускорителя PGI. Кроме того, если я исправлю его код так, что «c (i, j) = sum» помещается вне внутреннего цикла «k», время модели PGI Accelerator уменьшается до 123 мс. Непонятно, как он собрал свои тайминги.

Благодаря тем, кто пытался помочь. - Mat

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