• 検索結果がありません。

斉次更新の実装

ドキュメント内 JAIST Repository https://dspace.jaist.ac.jp/ (ページ 36-41)

第 3 章 GPGPU 17

4.2 斉次更新の実装

Ψ

(

r!1,⋯,r!i′,⋯,r!N

)

Ψ

(

r!1,⋯,r!i,⋯,r!N

)

CPU

GPU

Update Accept / Reject Next update r!1,⋯,!

ri,⋯,! rN

( )

!

r1,⋯,r!i,⋯,! rN

( )

r!1,⋯,! ri+1,⋯,!

rN

( )

!

r1,⋯,r!i+1 ,⋯,! rN

( )

Repeat N times

! ′

r

i

! ′

r

i+1

φ1( )!ri = a1s s=1

64 Θs( )r!i

φL

! ri

( )= aLs

s=1

64 Θs( )r!i

φ1( )!ri+1 = a1s s=1

64 Θs( )!ri+1

φL

! ri+1

( )= aLs

s=1

64 Θs( )r!i+1

Fig. 4.2: 逐次更新アルゴリズム

単純実装(逐次更新の換装)段階における計算の流れを Fig.4.2に示す.任意の電子位 置をCPU上で更新後(!ri →!ri$), 試行関数を構成するφj(!ri$) の再評価のために,それを得 るのに必要なデータをGPUに転送し,φj(!r$i)をGPU上で構築する.構築されたφj(!ri$) はCPUへ戻し,試行関数を構成後,更新された電子位置の棄却/採択を行い,また次の 電子位置を更新する,という逐次更新の流れになる.上述の流れにおいて,!riと !ri+1の 更新はランダムで行なわれるため無関係である.したがって,!r1から!rN までの全電子の 軌道関数φj(!r$1)からφj(!r$N) をGPU上で一度に処理する構造(斉次更新)に変更できれ ば,GPGPU並列数を逐次更新の電子数N 倍にすることが可能である.次節ではこの斉 次更新の実装について述べる.

Ψ

(

r!1′,⋯,r!i,⋯,r!N

)

Ψ

(

r!1,⋯,r!i,⋯,r!N

)

Ψ

(

r!1,⋯,r!i,⋯,r!N

)

Ψ

(

r!1,⋯,r!i,⋯,r!N

)

CPU

GPU

Update all

Accept / Reject

!′

r1,⋯,r!i,⋯,r!N

( )

! ⋮

r1,⋯,r!i′,⋯,r!N

( )

! ⋮ r1,⋯,!

ri,⋯,r!N

( )

! ′ r

i

φ1

! r1

( )= a1s

s=1

64 Θs( )!r1

φL

! r1

( )= aLs s=1

64 Θs( )r!1

φ1

! rN

( )

= a1s

s=1

64 Θs

( )

r!N

φL

! rN

( )

= aLs

s=1

64 Θs

( )

!rN

Fig. 4.3: 斉次更新アルゴリズム

進めるために,まずは斉次更新のCPU処理版を構築し,統計誤差範囲での一致を確認の 上,斉次更新CPU版を段階的にGPUに換装した.

4.2.2 斉次更新の GPU 換装

次に斉次更新処理を以下のようにGPU上に換装した:この段階では,§4.1で行なった のと同様に,相異なる格子点sでの積算をスレッドにアサインする(スレッド内の演算は 唯一つの積算のみ).斉次更新への変更に伴い,軌道のインデックスjに加え,電子のイ ンデックスiに関する並列性が加わる.これを(j, i)という二次元構造のブロックで処理 する(→Fig.4.4).

結果がTable 5.2に示されている.スレッド数は64で,逐次更新の場合と変わらないが

ブロック数が(電子数N×軌道数L)に増加したことで,並列度が大幅に向上し,216電 子の場合,6.39倍,1536電子の場合には5.61倍の高速化が達成された.

φj

!′ r1

( )

=aj1Θ1

( )

r!1 +aj2Θ2

( )

r!1+,⋯,+aj64Θ64

( )

r!1

φk

!′ r1

( )

=ak1Θ1

( )

r!1 +ak2Θ2

( )

r!1+,,+ak64Θ64

( )

r!1

各スレッドで処理

ブロック

に分割

φL

( )

r!1 =aL1Θ1

! r1

( )

+aL2Θ2

! r1

( )

+,⋯,+aL64Θ64

! r1

( )

φj

!′ rN

( )

=aj1Θ1

( )

!rN +aj2Θ2

( )

r!N +,⋯,+aj64Θ64

( )

r!N

φk

!′ rN

( )

=ak1Θ1

( )

r!N +ak2Θ

2

( )

!rN +,,+ak64Θ64

( )

r!N

φL

! rN

( )

=aL1Θ1

( )

!rN +aL2Θ2

( )

r!N +,⋯,+aL64Θ64

( )

r!N

Fig. 4.4: 斉次更新におけるブロックとスレッドの割り当て

cavc ( j, x, y, z, spin)! M×M×M! 4×4×4=64

ajs

Fig. 4.5: cavcとajsの関係

4.2.3 スレッディング構造の改変と最適化

前節までの逐次更新および斉次更新では,積和算

"64 s=1

ajsΘs(!ri) (4.2)

において,各スレッドでajsΘs(!ri)を計算し,スレッド間のリダクションにより総和が計算 された.係数ajsのデータ構造に着目し,ランダムアクセスを解消するようなスレッディ ング構造の組み換えを試みたところ,大きな性能向上を達成することが出来た:係数ajs

はcavcという配列名で,cavc(j, x, y, z, spin)の5次元配列に格納されている.jは軌道の インデックス,x, y, zは格子点のインデックス,spinは電子スピンに関するインデックス である.本研究では非偏極系を取り扱うため,スピンのインデックスは退化・消失する.

x, y, zに関する要素数はM ×M ×M で,216電子系の場合M = 60,1536電子系では

M = 50である.

グローバルメモリ上に置かれたcavc(j, x, y, z, spin)に対し,各電子位置!riを担当するス レッドは,!ri近傍の4×4×4 = 64点の格子点でのajsの値にアクセスする(→Fig.4.5).

前節までの逐次更新,および,斉次更新の実装では相異なるsがスレッドにアサインされ ているため,sを足とする連続メモリアクセスが発生するが,cavc配列はメモリ構造上,

jを足にとる1次元配列である.したがって,cavcへのアクセスはメモリアドレス上,飛 び飛びのランダムアクセスとなってしまう.この場合,§3.4で述べたとおり,レイテンシ の大きいグローバルメモリへのアクセスが大量に発生し,高速化を妨げる.これを避ける には,各スレッドが,軌道のインデックスjを足とした1次元配列cavcへの連続アクセス を構成するようにスレッディングを組み替え,コアレッシングを行なう必要がある.この 場合,相異なる軌道jがスレッドにアサインされることになる.スレッド内の演算は,あ る一つの軌道関数を構築する(4.2)式の64項の積和算となる.残されたインデックスであ

るi(電子インデックス)についてブロック化を行なった.すなわち,同一の電子インデッ

クスi を有する複数のスレッド(L本)がブロックにまとめられ処理される(→Fig.4.6).

前節までの実装ではスレッドで並列処理されていたs=1〜64の積和算は,本実装では,

各スレッドのループ内で処理される.この構造により,従来ではスレッド間で行なってい たリダクション処理の必要がなくなった.jをスレッド並列にしたことで,以前の実装で のΘs(!ri)に関する連続アクセスが失われる.しかしながら,一つのブロック(電子イン デックスiが固定)は,高々,64要素の同一のΘs(!ri)を参照するため,再利用性があり,

キャッシュによる効果が期待される:あるWarpが一度,グローバルメモリ上にあるΘs(!ri) にアクセスすると,その近傍の配列は,L1やL2キャッシュに保持され,キャッシュヒッ トが起きやすく,Θs(!ri)に関する連続アクセスの喪失はメモリアクセス遅延上の問題に はならないと期待される.

結果がTable 5.2に示されているが,この実装で最終的に216電子の場合,16.58倍,1536 電子の場合には30.67倍の高速化が達成された.

φj

( )

r!1 =aj1Θ1

( )

r!1 +aj2Θ2

( )

r!1+,,+aj64Θ64

( )

r!1

φk

( )

!r1 =ak1Θ1

( )

r!1+ak2Θ2

( )

!r1+,⋯,+ak64Θ64

( )

r!1 各スレッド で処理

ブロックに分割

φL

( )

r!1 =aL1Θ1

( )

!r1 +aL2Θ2

( )

r!1+,⋯,+aL64Θ64

( )

r!1

φj

! rN

( )

=aj1Θ1

( )

r!N +aj2Θ2

( )

r!N +,,+aj64Θ64

( )

r!N φk

( )

r!N =ak1Θ1

( )

!rN +ak2Θ

2

( )

r!N +,⋯,+ak64Θ64

( )

r!N

φL

! rN

( )

=aL1Θ1

( )

r!N +aL2Θ2

( )

r!N +,⋯,+aL64Θ64

( )

!rN

Fig. 4.6: 最適化によるブロックとスレッドの割り当て

ドキュメント内 JAIST Repository https://dspace.jaist.ac.jp/ (ページ 36-41)

関連したドキュメント