インテルのifortコンパイラv16でコンパイルされたFortranコードで簡単なDot Product計算を並列処理する方法を理解しようとしています。以下、より複雑なプロセスのために使用されるプログラムの一部ですが、ほとんどの時間はプログラムで費やされている場所です:ドットプロダクトの並列処理
double precision function ddot(n,dx,incx,dy,incy)
c
c forms the dot product of two vectors.
c uses unrolled loops for increments equal to one.
c jack dongarra, linpack, 3/11/78.
c modified 12/3/93, array(1) declarations changed to array(*)
c
double precision dx(*),dy(*),dtemp
integer i,incx,incy,ix,iy,m,mp1,n
c
CALL OMP_SET_NUM_THREADS(12)
ddot = 0.0d0
dtemp = 0.0d0
if(n.le.0)return
if(incx.eq.1.and.incy.eq.1)go to 20
c
c code for unequal increments or equal increments
c not equal to 1
c
ix = 1
iy = 1
if(incx.lt.0)ix = (-n+1)*incx + 1
if(incy.lt.0)iy = (-n+1)*incy + 1
do 10 i = 1,n
dtemp = dtemp + dx(ix)*dy(iy)
ix = ix + incx
iy = iy + incy
10 continue
ddot = dtemp
return
c
c code for both increments equal to 1
c
c
c clean-up loop
c
20 m = mod(n,5)
if(m .eq. 0) go to 40
!$OMP PARALLEL DO
!$OMP& DEFAULT(NONE) SHARED(dx,dy,m) PRIVATE(i)
!$OMP& SCHEDULE(STATIC)
!$OMP& REDUCTION(+ : dtemp)
do 30 i = 1,m
dtemp = dtemp + dx(i)*dy(i)
30 continue
!$OMP END PARALLEL DO
if(n .lt. 5) go to 60
40 mp1 = m + 1
!$OMP PARALLEL DO
!$OMP& DEFAULT(NONE) SHARED(dx,dy,n,mp1) PRIVATE(i)
!$OMP& SCHEDULE(STATIC)
!$OMP& REDUCTION(+ : dtemp)
do 50 i = mp1,n,5
dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) +
* dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4)
50 continue
!$OMP END PARALLEL DO
60 ddot = dtemp
return
end
私はOpenMPのコマンドに新しいですし、私が何かを持っているかなり確信しています面白いところがありますが、全体を単一のコアよりも遅くすることができます。現在私は、遅い4(4)コアマシンで4スレッドで実行しようとしましたが、実際には12スレッドを処理用に指定した大きな20(40)コアマシンよりも少し速くなりました。この時点で私はコードが面白いと思っていて、私が欲しくないことをしています。
Doループの上位レベルも並列化することができますが、ix
とiy
の定義方法はわかりませんでした。
精度は非常に重要なので、コンパイラはfp-modeに正確に設定されています。私はそれがまったく問題なのかどうかはわかりませんが、コードが回答を生成することができれば、正しいと思われます。基本的には、このコードの高速化の方法を理解しようとしていますが、代わりに並列処理では処理が遅くなるようです。
Ufでは、 'CONTINUE'ではなく' END DO'を使うことをお勧めします。本当にコードを読むのは難しいです。 –
Intelは、MKLライブラリのlinpack ddotを高速化するすべての作業を行っています。とりわけ、これはアンロールを5で破棄し、いくつかのターゲットアーキテクチャを最適化することを含む。あなたは、単一スレッドのsimd削減が数千のサイズまで使用されていることが分かります(dot_productは小規模なケースを処理できます)。fp-model preciseは、ユーザーの制御からの精度の改善をわずかには避けるため、最適化された縮小を防ぎます。 – tim18
Intelは通常VIPOと言っています... "vector inner" "parallel outer"。私はそれをすべて「平行do」から「SIMDを行う」に変更します。得られるべきものがあれば、最も外側の部分に平行します。 VIの部分は簡単ですが、キャッシュミスがあれば遅くなります。あなたがifortを持っているなら、あなたはvtuneを持っていますか? – Holmz