Upload
tranngoc
View
219
Download
0
Embed Size (px)
Citation preview
OpenFOAMスレッド並列化のための基礎検討
富岡稔*(株式会社フィックスターズ)伊藤優希(株式会社フィックスターズ)丸石崇史(株式会社フィックスターズ)𠮷藤尚生(株式会社フィックスターズ)
© 2017 Fixstars Corporation, All rights reserved.
概要
OpenFOAMのスレッド並列化を行ってIntel
Xeon PhiなどのメニーコアCPU上での高速化を目指す
今回はそのための基礎検討として、pimpleFoamなどで使用されるlduMatrixクラスの線形ソルバPCGのスレッド並列化を検討した
1
© 2017 Fixstars Corporation, All rights reserved.
OpenFOAMの並列計算
MPIによるプロセス並列のみ
メニーコアCPUで効率よく計算するにはスレッド並列も用いるべき
2
© 2017 Fixstars Corporation, All rights reserved.
なぜ今基礎検討なのか?
過去にはMPIとスレッド並列を組み合わせたHybrid並列を実装し、「京」コンピュータにて評価しているものが存在する[1]
→ MPIのみのものと同等の性能
同様にスレッド並列化を行っている例は複数存在しているがコードはOpenFOAMに取り込まれていない
ゼロベースで作ることで知見を得る それによって高速化したい
3
© 2017 Fixstars Corporation, All rights reserved.
(1) 内山学,ファムバンフック,千葉修一,井上義昭,浅見暁,OpenFOAMによる流体コードのHybrid並列化の評価,情報処理学会研究報告,Vol.2015-HPC-151,No.20,pp.1-6, (2015)
概要
OpenFOAMのスレッド並列化を行ってIntel
Xeon PhiなどのメニーコアCPU上での高速化を目指す
今回はそのための基礎検討として、pimpleFoamなどで使用されるlduMatrixクラスの線形ソルバPCGのスレッド並列化を検討した
4
© 2017 Fixstars Corporation, All rights reserved.
前処理付き共役勾配法(PCG)
線形方程式を解く反復法の一種
反復内の主な処理
➢前処理 (𝑀−1𝒓)
➢内積 (𝒓1 ∙ 𝒓2)
➢ベクトル和 (𝒓1 + 𝒓2)
➢ベクトルのスカラー倍 (𝛼𝒓)
➢疎行列ベクトル積 (𝐴𝒓)
5
© 2017 Fixstars Corporation, All rights reserved.
PCGのボトルネック
前処理を対角ベース不完全コレスキー分解(DIC)
の場合の実行時間を計測
計測にはオープンCAE学会がベンチマークとして作成したチャネル流問題[2]を使用
ボトルネックはDIC前処理と疎行列ベクトル積
どちらも行列演算でlduMatrixクラスを使用
→ 並列性はlduMatrixクラスに依存
6
© 2017 Fixstars Corporation, All rights reserved.
(2) OpenFOAM Benchmark Test for Channel Flow (Re_tau=110),
https://github.com/opencae/OpenFOAM-BenchmarkTest/tree/master/channelReTau110, (accessed 2017-11-17)
lduMatrixクラスの疎行列格納形式
lduMatrixクラスは疎行列を対角部分D, 上三角部分U, 下三角部分Lに分けてそれぞれの非ゼロ要素を保持
Uは行優先、Lは列優先で格納
非ゼロ要素に対応する行と列の情報も保持
→ COO形式と等価
7
© 2017 Fixstars Corporation, All rights reserved.
𝑈
𝐿
𝐷
lduMatrixクラス(具体例)8
© 2017 Fixstars Corporation, All rights reserved.
1 5 62
8 3 79 10 4
diag = 1, 2, 3, 4upper = 5, 6 7lower = 8, 9, 10lowerAddr = 0, 0, 2upperAddr = 2, 3, 3
𝑈
𝐿
𝐷
対角部分の値上三角部分の値下三角部分の値上三角部分の行番号・下三角部分の列番号上三角部分の列番号・下三角部分の行番号
lduMatrixクラスの問題点
下三角部分Lを列優先で保持している
→ 非ゼロ要素の行番号が連続していない
疎行列ベクトル積やDIC前処理をスレッド並列化するとアクセス競合が発生する
lduMatrixクラスを用いている部分は
スレッド並列化が困難
9
© 2017 Fixstars Corporation, All rights reserved.
疎行列ベクトル積(lduMatrix)
𝒚 = 𝐴𝒙⇔各非ゼロ要素𝑎𝑖𝑗に対して 𝑦𝑖 += 𝑎𝑖𝑗 𝑥𝑗 を計算
10
© 2017 Fixstars Corporation, All rights reserved.
const label nCells = diag().size();for (label cell = 0; cell < nCells; cell++) {
A[cell] = diag[cell]*x[cell];}
const label nFaces = upper().size();for (label face = 0; face < nFaces; face++) {
A[upperAddr[face]] += lower[face]*x[lowerAddr[face]];A[lowerAddr[face]] += upper[face]*x[upperAddr[face]];
}
具体例
異なるループ変数で同じ場所を書き換える
→ 並列化すると同時書き込みが発生
11
© 2017 Fixstars Corporation, All rights reserved.
1 5 62
8 3 79 10 4
const label nFaces = upper().size();for (label face = 0; face < nFaces; face++) {
A[upperAddr[face]] += lower[face]*x[lowerAddr[face]];A[lowerAddr[face]] += upper[face]*x[upperAddr[face]];
}
face 0 1 2
upper 5 6 7
lower 8 9 10
lowerAddr 0 0 2
upperAddr 2 3 3
DIC前処理(lduMatrix)
前処理は 𝒛 = 𝑀−1𝒓= 𝐼 + 𝐷∗−1𝑈 −1 𝐼 + 𝐷∗−1𝑈𝑇 −1𝐷∗−1𝒓で計算
→ 前進代入・後退代入
12
© 2017 Fixstars Corporation, All rights reserved.
←前進代入
←後退代入
for (label cell = 0; cell < nCells; cell++) { z[cell] = invD [cell]*r[cell];
}
for (label face=0; face < nFaces; face++) { z[upperAddr[face]] -=
invD[upperAddr[face]]*lower[face]*z[lowerAddr[face]];}
for (label face = nFaces-1; face >= 0; face--) {z[lowerAddr[face]] -=
invD[lowerAddr[face]]*upper[face]*z[upperAddr[face]];}
具体例
ループ内の異なるfaceで同じ場所を書き換える
→ 並列化すると同時書き込みが発生
13
© 2017 Fixstars Corporation, All rights reserved.
1 5 62
5 3 76 7 4
for (label face = 0; face < nFaces; face++) { z[upperAddr[face]] -=
invD[upperAddr[face]]*lower[face]*z[lowerAddr[face]];}
face 0 1 2
lower 5 6 7
lowerAddr 0 0 2
upperAddr 2 3 3
対策
lduMatrixクラスのままではスレッド並列化が困難
→ 別の形式に変換
今回はCSR形式で考える
14
© 2017 Fixstars Corporation, All rights reserved.
CSR形式
data[k]: k番目の非ゼロ要素の値
column[k]: k番目の非ゼロ要素の列番号
offset[i]: i行目のdataとcolumnの開始位置
15
© 2017 Fixstars Corporation, All rights reserved.
1 5 62
8 3 79 10 4
data = [1, 5, 6, 2, 8, 3, 7, 9, 10, 4] column = [0, 2, 3, 1, 0, 2, 3, 0, 2, 3]offset = [0, 3, 4, 7, 10]
疎行列ベクトル積(CSR形式)
𝒚 = 𝐴𝒙⇔各非ゼロ要素𝑎𝑖𝑗に対して 𝑦𝑖 += 𝑎𝑖𝑗 𝑥𝑗 を計算
それぞれ違う場所を書き換える
→ 並列化が可能
16
© 2017 Fixstars Corporation, All rights reserved.
for (label i = 0; i < n; i++) {double work = 0.0;for (label index = offset[i]; index < offset[i + 1]; index++) {
work += data[index] * x[column[index]];}y[i] = work;
}
DIC前処理(CSR形式)
前処理は 𝒛 = 𝑀−1𝒓= 𝐼 + 𝐷∗−1𝑈 −1 𝐼 + 𝐷∗−1𝑈𝑇 −1𝐷∗−1𝒓で計算
→ 前進代入・後退代入
17
© 2017 Fixstars Corporation, All rights reserved.
for (label i = 0; i < n; i++) {z[i] = invD[i]*r[i];
}
for (label i = 0; i < n; i++) {double work = z[i];for (label index = offset[i]; index < offset[i+1]; index++) {
const auto j = column[index];if (j < i) {
work -= invD[i] * data[index] * z[j];}
}z[i] = work;
}
まだ並列化できない
データ依存性によりCSR形式でも単純にはスレッド並列化できない
→ Cuthill-Mckee法・Multicolor法
18
© 2017 Fixstars Corporation, All rights reserved.
for (label i=0; i<n; i++) {double work = z[i];for (label index = offset[i]; index < offset[i+1]; index++) {
const auto j = column[index];if (j < i) {
work -= invD[i] * data[index] * z[j];}
}z[i] = work;
}
まとめ
OpenFOAMのPCGのスレッド並列化のための基礎検討を行った
lduMatrixクラスの行列格納形式が原因でそのままでは並列化が困難である
CSRに変換することでPCGのスレッド並列化の可能性を示唆した
19
© 2017 Fixstars Corporation, All rights reserved.
今後の展望
DIC-PCGのスレッド並列を実装
メニーコアCPUの環境でスレッド並列化したDIC-PCGの実行時間を計測
フラットMPIによる並列計算と比較・評価し、コード公開
今回検討した部分以外もスレッド並列化を進める➢DIC以外の前処理
➢PCG以外の線形ソルバ
➢ lduMatrixクラス以外の処理
最終的にはOpenFOAM全体のスレッド並列化
20
© 2017 Fixstars Corporation, All rights reserved.