ToDo:
実装してみたものの性能が微妙 orz
比較対象は、LinearSolveRealで実装しているLinearSolveComplex1 (MxN 複素行列上の代数を、等価な 2Mx2N 実行列上で計算する) な訳ですが、ある程度の大きさの正方行列の逆行列を計算させた場合
MxN | BLAS | LinearSolveComplex | LinearSolveComplex1 |
128x128 | Netlib | .118 ± .001 sec | .171 ± .001 sec |
256x256 | Netlib | .945 ± .007 sec | 1.449 ± .008 sec |
512x512 | Netlib | 9.623 ± .290 sec | 12.692 ± .103 sec |
1024x1024 | Netlib | 111.400 ± 3.128 sec | 129.272 ± 3.877 sec |
128x128 | GotoBLAS | .085 ± .004 sec | .089 ± .001 sec |
256x256 | GotoBLAS | .648 ± .004 sec | .555 ± .004 sec |
512x512 | GotoBLAS | 6.452 ± .129 sec | 4.438 ± .024 sec |
1024x1024 | GotoBLAS | 84.66 ± .21 sec | 40.71 ± .33 sec |
(Core2 Duo T7200(2GHz))
演算精度は、小行列で試した範囲では、LinearSolveComplexの方が若干良いようです。
原因としては
辺りが疑わしいです
当初予定分(LinearSolve, SingularValues, Eigensystem)は完成した。
SAD core側にも作業の余地はあるのだが、BLAS & LAPACKに依存することに なるので、インストール作業の手数が増えると質問続出になりそうなので、 ボトルネックになる事案が判明するまで放置する予定。
実用上改善の余地が有りそうな所としては、行列の Dot積(内部的にInner[]を 呼び出している?)辺りと専用の関数経由でGEMMを使わせると速くなるのでは 無いかと妄想中。(データ解析等で大きめの行列の行列積が出てくる)
SpaceCharge/Scheff moduleの経験からは有為な改善がありそうだが.... コストに見合うだけのボトルネックになっているか問題である。
ほかにも、Fortranコンパイラベンダ謹製の最適化BLAS & LAPACKがあるようです
手元の Opteron 2376で測定した固有値分解(*GEEVX)やSVD(*GESDD)の single core性能だと
GotoBLAS-2.1.3 > ACML-4.0.0 > ATLAS-3.9.11 >> ATLAS-3.8.3 >> LAPACK-3.2.2
でした。
ATLASに関しては、3.9.3辺り QR分解まわりの改良が効いてるのか安定版と 大きな性能差が出ました。
トップ3ライブラリの差は10%前後ですが、GotoBLASの速さが目立ちました。 (ACML-4.0.0と ATLAS-3.9.11は、結構接戦でした)
まとめると...
FreeBSDの math/atlas-develが 3.9.11で止まってたので、 3.9.32の野良portsを作ったがうまく動かないので深追いしてたが、やっと成功。
コンパイルテストに長い時間がかかって苦労したけど、原因は至って簡単orz
tune/blas/gemvとtune/blas/gerで止まる問題は、生成された Makefileが 依存関係の解決にGNU makeで無いと問題が出る部分が有るにも関わらず*.c系から 吐き出す shell command lineで make utilityの名前がmakeで 決め打ちになっているためだった。 (つまり、GNU makeでビルドしても途中で BSD makeが呼び出されて詰まる) この手の問題は、Linux上や darwin系では起こらない orz
細かなものでは、atlas_[sdcz]r[12].hとかatlas_[sdcz]mv[nt].hの 扱いに問題が有って BSD makeだとルール最後の mvコマンドの失敗で ルールが失敗扱いになってビルドが停止する問題も有りました。
これらは、makes/Make.mvtuneとmakes/Make.r1tuneにパッチを当てて修正
Kernel Tuningがらみだと、Opteron 2376で L1 Cacheが 1kBと検知される問題 が有ったのですが、tune/sysinfo/GetSysSum.cでGetL1CacheSize()に渡す L1 Cache Size探索の上限が 64kBしか無いので、L1 Cache Size Edgeでは無く 命令バッファか何か他のEdgeを検出するためで、探索上限を 256kBとかにすると 正しく 64kBのL1 Cacheを検知しました。 (ports-CURRENTのpatch-tune+sysinfo+L1CacheSize.cの修正だけでは、 後一歩足りない罠)
カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記