xeonphiハッカソンでexpを作ってみた
TRANSCRIPT
![Page 1: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/1.jpg)
第1回XeonPhiハッカソン
2013/8/3 光成滋生
![Page 2: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/2.jpg)
やったこと
• 自作の近似指数関数double exp(double)をXeonPhiに移植する
![Page 3: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/3.jpg)
結果
• icpcに負けた
–実装コード
• https://github.com/herumi/misc/blob/master/exp-xeonphi.cpp
![Page 4: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/4.jpg)
作業内容を振り返る
• 既存のベンチマーク
– Phiが載ってるマシン Xeon E5-2620@2GHz
• gcc 4.4.7での比較(clk:小さいほど速い)
• icpc 13.1.3での比較
– Xeon上ではicpcには勝ってる
scalar loop(vector)
std 285 286
fmath 14 8.5
scalar loop(vector)
std 26 9.8
fmath 13.35 7.7
![Page 5: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/5.jpg)
Phi上のC(not intrinsic)の評価
• scalar版が勝ってるので速くなるかもと期待
scalar loop(vector)
std 85 14
fmath 78 後ほど
![Page 6: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/6.jpg)
intrinsic-SSE版をPhiに移植開始
• __m128d → __m512d
• alignは16byteから64byte単位へ
–忘れると多分落ちる
• _mm_mul_pd → _mm512_mul_pdなど
– このあたりは形式的に可能
![Page 7: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/7.jpg)
シャッフルではまる
• x[]の偶数番目だけをy[]に入れる
• x = [...:7:6:5:4:3:2:1:0] → y = [...x4:x2:x0]
• vpermd(_mm512_permutevar_epi32)を使った
– int ptn[16] = { 0, 2, 4, 6, 8, 10, 12, 14 };
– __m512i selEven = (* __m512i*)ptn;
– y = _mm512_permutevar_epi32(selEven, x);
• 引数の順序に注意
• もっとよい方法があるかもしれない(教えてください)
![Page 8: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/8.jpg)
gatherを使ってみる
• SSE版は一つずつ読んでpackでくっつける
– Haswellのgatherは次回作に期待?(by 中村さん)
– int32のインデックスからdoubleを読む
• 対応する命令は_mm512_i32logather_epi64
• 遅いのかどうかは時間不足で計測できず
– zmmintrin.hには_mm512_prefetch_i32extgather_ps()とかあった
– これを使えばprefetchできる?
• 今回はindex確定してから利用まで短いので効果は出るか?
![Page 9: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/9.jpg)
シフト
• 64bit単位でのシフト命令を探す
–ない
–ない
– 32bit単位のシフトしかない
• ええ??
– 32bit単位でシフトしてorしてエミュレート?
– x=[H:L], x >>= s
• H >>= s, L >>= s, H = (H << (32-s)) >> 32
– byte単位のシフトもない
![Page 10: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/10.jpg)
32bit左シフト
• 時間がないので先程のvpermdを使った
– もっとよい方法があれば(略
__m512i shl32bit(__m512i x) { static const MIE_ALIGN(64) int m[16] = { 0, 0, 0, 2, 0, 4, 0, 6, 0, 8, 0, 10, 0, 12, 0, 14 }; static const __m512i y = *(__m512i*)m; __m512i zero = _mm512_setzero_epi32(); return _mm512_mask_permutevar_epi32(zero,0xaaaa,y,x); }
![Page 11: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/11.jpg)
実装結果
• 一応scalarの4倍速くなった
–がicpcの自動ベクトル化に負けた
• ヘッダには_mm512_exp_pd()という関数がある
• 言い訳
–まだ動くようにしただけ
• asm出力もみてない 最適化もしてない
• こちらは近似計算だし4clkぐらいはなんとかしたい
scalar loop(vector)
std 85 14
fmath 78 18
![Page 12: Xeonphiハッカソンでexpを作ってみた](https://reader030.vdocuments.site/reader030/viewer/2022020207/55959fd11a28ab05448b45d9/html5/thumbnails/12.jpg)
ToDo
• プリフェッチが効くらしい
– _mm_prefetchを入れてみたが遅くなった(25clk
–他の方法?
• vexp223psを使ってみたかった
– exp()の近似値を返す関数っぽい
• これはAVXにも欲しいAVX-512に期待
– これがあると多分最初のテーブル引きやgatherが不要になる
• が、多分アルゴリズムの修正が必要