0

私は多くの繰り返し (~10^6-10^7) を含むループを含むコードに取り組んでおり、配列 (「myresult」としましょう) が多くの貢献の合計を介して計算されています。OpenMP を使用する Fortran 90 では、次のようになります。

!$omp parallel do
!$omp& reduction(+:myresult)
do i=1,N
 myresult[i] = myresult[i] + [contribution]
enddo
!$omp end parallel

コードはインテル Xeon コプロセッサーを搭載したシステムで実行されますが、もちろん、可能であればその存在から恩恵を受けたいと考えています。OpenMP で MIC オフロード ステートメント (!dir$ offload target ...) を使用して、ループがコプロセッサだけで実行されるようにしましたが、コプロセッサが終了するのを待っている間、ホストの CPU 時間を無駄にしています。理想的には、ホストとデバイスの間でループを分割できるので、次のようなことが実現可能かどうか (またはより良いアプローチがあるかどうか) を知りたいです。ループはホスト上の 1 つのコアでのみ実行されます (ただし、おそらく OMP_NUM_THREADS=2 を使用しますか?):

!$omp parallel sections
!$omp& reduction(+:myresult)

!$omp section ! parallel calculation on device
!dir$ offload target mic
!$omp parallel do
!$omp& reduction(+:myresult)
(do i=N/2+1,N)
!$omp end parallel do

!$omp section ! serial calculation on host
(do i=1,N/2)

!$omp end parallel sections
4

2 に答える 2

0

一般的な考え方は、CPU が続行できるように、MIC への非同期オフロードを使用することです。作品の分割方法の詳細はさておき、次のように表現します。

module m
!dir$ attributes offload:mic :: myresult, micresult
integer :: myresult(10000)
integer :: result
integer :: micresult
end module

use m
N = 10000
result = 0
micresult = 0
myresult = 0
!dir$ omp offload target(mic:0) signal(micresult)
!$omp parallel do reduction(+:micresult)
do i=N,N/2
 micresult = myresult(i) + 55
enddo
!$omp end parallel do

!$omp parallel do reduction(+:result)
do i=1,N/2
 result = myresult(i) + 55
enddo
!$omp end parallel do

!dir$ offload_wait target(mic:0) wait(micresult)
result = result + micresult
end
于 2014-05-19T17:43:23.517 に答える