OpenMPによるPGI AcceleratorのマルチGPU化
出典: トータル・ディスクロージャ・サイト(事実をありのままに)
以前紹介した、PGI Acceleratorは、マルチGPUに対応しているようであるが、マルチGPU絡みの情報が不足している。今回は、OpenMPを用いて、PGI AcceleratorのプログラムをマルチGPU並列化するテストを行うことにした。
目次 |
マルチGPUのAPIについて
通常のCUDAのAPIである、cudaSetDeviceでは、PGI AcceleratorをマルチGPUに対応させることは、現状では不可能なようである。代わりとなるPGI AcceleratorのAPIは、以下のものである。なお、以下のAPIは、accel_libモジュールに含まれているので、事前にuseする必要がある。
- acc_get_num_devices
- システムに搭載されているGPUの数を返す。第1引数には、定数「acc_device_nvidia」を渡す。
- acc_set_device_num
- PGI Acceleratorが使うGPUを指定する。第1引数にGPU番号を入力し、第2引数に定数「acc_device_nvidia」を渡す。GPU番号は、最初のGPUが0で、以下1ずつ増えていく通し番号である。
プログラム例
簡単な行列積計算のPGI Acceleratorプログラムを、OpenMPを使って並列化する。並列化していないバージョンが、
PROGRAM MATMUL_MULTIGPU
USE OMP_LIB
USE ACCEL_LIB
IMPLICIT NONE
INTEGER I,J,K,N
PARAMETER(N=4000)
REAL A(N,N),B(N,N)
REAL*8 T1,T2,SUM
DO 20 J=1,N
DO 10 I=1,N
A(I,J)=REAL(I*N+J)/REAL(N*N)
10 CONTINUE
20 CONTINUE
CALL CPU_TIME(T1)
C$ACC REGION COPYIN(A), COPYOUT(B)
C$ACC DO PARALLEL PRIVATE(I,J,K)
DO 50 J=1,N
DO 40 I=1,N
B(I,J)=0.0
DO 30 K=1,N
B(I,J)=B(I,J)+A(I,K)*A(K,J)
30 CONTINUE
40 CONTINUE
50 CONTINUE
C$ACC END REGION
CALL CPU_TIME(T2)
WRITE(*,*)T2-T1,'SEC'
SUM=0.0
DO 70 J=1,N
DO 60 I=1,N
SUM=SUM+B(I,J)
60 CONTINUE
70 CONTINUE
WRITE(*,*)'CHECKSUM =',SUM
STOP
END PROGRAM MATMUL_MULTIGPU
であるところ、並列化して、
PROGRAM MATMUL_MULTIGPU
USE OMP_LIB
USE ACCEL_LIB
IMPLICIT NONE
INTEGER I,J,K,N
PARAMETER(N=4000)
REAL A(N,N),B(N,N)
REAL*8 T1,T2,SUM
INTEGER NGPU,IOMP,NOMP,JMIN,JMAX
DO 20 J=1,N
DO 10 I=1,N
A(I,J)=REAL(I*N+J)/REAL(N*N)
10 CONTINUE
20 CONTINUE
CALL CPU_TIME(T1)
NGPU=ACC_GET_NUM_DEVICES(ACC_DEVICE_NVIDIA)
C$OMP PARALLEL DEFAULT(NONE),NUM_THREADS(NGPU)
C$OMP& SHARED(N,A,B,ACC_DEVICE_NVIDIA)
C$OMP& PRIVATE(I,J,K,IOMP,NOMP,JMIN,JMAX)
IOMP=OMP_GET_THREAD_NUM()
NOMP=OMP_GET_NUM_THREADS()
CALL ACC_SET_DEVICE_NUM(IOMP,ACC_DEVICE_NVIDIA)
JMIN=IOMP*N/NOMP+1
JMAX=(IOMP+1)*N/NOMP
C$ACC REGION COPYIN(A), COPYOUT(B(1:N,JMIN:JMAX))
C$ACC DO PARALLEL PRIVATE(I,J,K)
DO 50 J=JMIN,JMAX
DO 40 I=1,N
B(I,J)=0.0
DO 30 K=1,N
B(I,J)=B(I,J)+A(I,K)*A(K,J)
30 CONTINUE
40 CONTINUE
50 CONTINUE
C$ACC END REGION
C$OMP END PARALLEL
CALL CPU_TIME(T2)
WRITE(*,*)T2-T1,'SEC'
SUM=0.0
DO 70 J=1,N
DO 60 I=1,N
SUM=SUM+B(I,J)
60 CONTINUE
70 CONTINUE
WRITE(*,*)'CHECKSUM =',SUM
STOP
END PROGRAM MATMUL_MULTIGPU
のような、acc_get_num_devicesでGPUの数を得た後、OpenMPでその数だけスレッドを走らせ、acc_get_device_numでOpenMPのスレッド番号のGPUを指定し、計算を行うプログラムとする。
実行環境
| CPU: | 6コア Xeon X5690 3.47 GHz × 2 |
| GPU: | Tesla M2090 × 4 |
| OS: | Windows 7 Professional SP1 |
| コンパイラ: | PGI Accelerator Workstation 11.10 |
| GPUドライバ: | バージョン276.42 |
実行結果
並列化前が
1.824000000000000 SEC CHECKSUM = 16017339253.05869
であったところ、マルチGPUでは
0.697000000000000 SEC CHECKSUM = 16017339253.05869
となり、1.824秒:0.697秒 = 約2.62倍の並列化効果が、マルチGPU化によって出ていることがわかる。
この記事へのコメントをお寄せください
- サイトへの書き込みに差し支えございましたら トータルディスクロージャーサイトサポート係へメールをお送りください 。
- トータル・ディスクロージャ・サイトに投稿された文章と画像は、すべてその著作権がHPCシステムズ株式会社に帰属し、HPCシステムズ株式会社が著作権を所有することに同意してください。
- あなたの文章が他人によって自由に編集、配布されることを望まない場合は、投稿を控えてください。
- コメントを書き込む場合は名前にひらがなを織り交ぜてください。
- あなたの投稿する文章と画像はあなた自身によって書かれたものであるか、パブリック・ドメインかそれに類する自由なリソースからの複製であることを約束してください。あなたが著作権を保持していない作品を許諾なしに投稿してはいけません!
