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

これを実行すると、アクセラレータディレクティブとPGIコンパイラを使用した場合の実行時間は75ミリ秒になります。しかし、「cuda fortran」実装で同じ行列乗算を実行すると、実行時間はわずか5ミリ秒です。したがって、アクセラレータディレクティブを使用したとしても、大きな違いがあります。したがって、アクセラレータディレクティブが正しく機能しているとは思えません。

4

2 に答える 2

1

非常によく似たアクセラレータ ディレクティブ OpenHMPP を使用して、プログラムを高速化しようとしました。私はあなたの行を1つ切り替えたことに注意してください。これはおそらく誤って最も内側のループにあります。また、削減が行われていることをコンパイラにアドバイスする必要があったことにも注意してください。また、reduction 変数の名前を変更しました。これは、sum組み込み関数を隠しているためです。

GPU カーネルの起動に伴うオーバーヘッドとメモリ転送のため、パフォーマンスは良くありません。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)

于 2012-03-20T16:47:59.637 に答える
0

参考までに、OP はこの質問を PGI ユーザー フォーラム (http://www.pgroup.com/userforum/viewtopic.php?t=3081) にも投稿しました。元の問題はパイロット エラーの結果であると考えています。CUDA Prof を使用して彼のコードをプロファイリングしたところ、CUDA Fortran カーネルの実行時間は 205 ミリ秒でしたが、PGI アクセラレータ モデルを使用した場合は 344 ミリ秒でした。また、「c(i,j)=sum」が内側の「k」ループの外側に配置されるようにコードを修正すると、PGI アクセラレータ モデルの時間は 123ms に短縮されます。彼がどのようにタイミングを計ったかは不明です。

助けようとした人に感謝します。- マット

于 2012-03-26T22:34:36.157 に答える