Contenu connexe
Similaire à X86opti01 nothingcosmos (20)
Plus de nothingcosmos (7)
X86opti01 nothingcosmos
- 1. 本物の X86Optimizer は
icc を使う
Outline
1. X86 なら icc だよね!
2. コンパイラと協調した最適化
3. 各種オプションの詳細
2011/08/06 X86/X64 最適化勉強会 1
nothingcosmos <nothingcosmos@gmail.com>
- 2. プロフィール
HN:nothingcosmos
コンパイラ屋歴 6 年くらい
X86 アセンブリプログラミング経験は少なめ
X86 を最適化する上で、
コンパイラと上手に付き合うための方法を紹介
決して Intel の回し者ではありませんので、、
- 3. X86 なら ICC だよね!
Linux 版の IntelCompiler およびライブラリは
非商用において、無償でつかえる
Linux 版 URL:http://goo.gl/nOeTP
今回の資料は、 Intel Composer XE 2011
最適化クイック・リファレンス・ガイド
をちょっと掘り下げています。
- 4. icc のコンパイルオプション
Icc に一番速いやつで頼むオプションは、 fast
fast = xHOST O3 ipo noprecdiv static
xHOST : ホストで最速な命令セットを使用する
O3 : speed 最優先のアグレッシブな最適化
ipo : プロシージャ間の最適化
noprecdiv: 浮動小数点精度の向上
static : 共有ライブラリを使用せず、内部に取り込む
- 5. コンパイラと協調した最適化
コンパイラオプションでチューニングする
プロシージャ間の最適化
手軽
プロファイルに基づいた最適化
きめ細やかなチューニングオプション
pragma directive 等の使用
手でボトルネック部分を最適化する
コンパイラのレポート機能の活用 効果高い
Vtune などのパフォーマンスアナライザの活用
SIMD 等のアセンブリプログラミング
- 6. コンパイラと協調した最適化
コンパイラオプションでチューニングする
プロシージャ間の最適化
手軽
プロファイルに基づいた最適化
きめ細やかなチューニングオプション
コンパイラ担当なので、
コンパイラオプションの紹介をします 効果高い
ハンドオプティマイズや
SIMD アセンブリプログラミングなんかは
他の方が紹介してくれるそうなので
- 7. ここからオプションの詳細
プロシージャ間の最適化 (IPO)
プロファイルに基づいた最適化 (PBO)
きめ細やかなチューニングオプション
ループアンローリング
ソフトウェアプリフェッチ
エイリアシング
既にご存知の方はどのくらい???
- 8. プロシージャー間の最適化
複数ファイルに跨った最適化を有効にする
複数ファイルのコンパイル時に効果を発揮する
別ファイルの関数の inline 展開、メモリレイアウトの改善
別名解析の精度向上、不要なシンボルの除去に伴うプログラムサイズの改善
複数ファイルをコンパイルする coremark で性能測定
20297 iterations O3 xHOST fargumentnoalias
20533 iterations O3 xHOST fargumentnoalias ipo
- 9. プロシージャー間の最適化
普通のコンパイルプロセス
a.c a.s a.o
cc as ld a.out
b.c a.s a.o
IPO(LTO) のコンパイルプロセス
a.c a.il
cc1 cc2 a.s as ld a.out
b.c a.il
icc は ipo を付与すると、 o ファイルに __ildata が埋まっている
gcc は gimple レベル、 llvm は bitcode レベルで行う。
- 10. プロシージャー間の最適化
JVM は必要なクラスを全て取り込んだ状態で JIT コンパイルするので
プロシージャ間と考え方は同じ。
積極的に inline 展開や脱仮想化を試行できる
classloader が上記を阻害するけど、脱最適化と再コンパイルで回避
IPO や LTO の注意点として
llvm(O4, stdlinkopts, internalize) は、
1 つの実行ファイルとして仮定して最適化し、シンボルの static 化を行う。
他からの参照があると、 ld で見つからないことも。。
- 11. プロファイルに基づく最適化
プロファイル情報を使用してさらに高度な最適化を行う
使うためには、 3 段階の手順が必要
1. $ icc profgen O0 xxx.c 関数の埋め込み
2. $ ./a.out プロファイル情報の収集
3. $ icc profuse fast xxx.c 最適化を有効化
Coremark も性能向上。ほんのちょっと。
19404 iterations fast
19531 iterations fast profuse
20567 iterations fast fargumentnoalias
21398 iterations fast fargumentnoalias profuse 4% 性能向上
- 12. プロファイルに基づく最適化
profgen を指定すると、関数の入口
出口、分岐に命令を埋め込む
関数やブロックの実行回数、
分岐確率等をファイルに記録し、
最適化に活かすことができる。
JVM はインタプリタ実行時に取得
↓llvm 的にはこんな感じ
- 13. プロファイルに基づく最適化
PGO の利点
分岐予測の最適化が改善される。マニュアルの 3.4.1
過度なループ展開、ベクトル化、プリフェッチの抑止
細かい最適化テクニックを駆使するよりも、
PGO に任せた方がよい。
プロファイルのパラメータと異なる場合、性能劣化の可能性
プロファイル結果に敏感なコンパイラの場合は注意
icc はあまり劣化するようなことはしないが、
java server コンパイラなんかは積極的に活用します
- 14. きめ細かなチューニングオプション
インテル ComposerXE2011
最適化クイック・リファレンス・ガイドより
unroll[n]
optprefetch[n]
fargument[no]alias
- 15. きめ細かなチューニングオプション
unroll[n]
ループ展開の最大数 n を指定する。 0 で展開無効化
ループを n 倍展開すると、様々な恩恵を得て性能向上
やりすぎると様々なキャッシュがオーバーして性能劣化
個人的には、
しきい値の調整は PGO に
任せればいいんじゃないか
と思ってます。
- 16. きめ細かなチューニングオプション
unroll[n]
ループ展開の効果を coremark で測定
共通オプション fast fargumentnoalias
20107 iterations unroll0
20338 iterations unroll2 ← デフォ
20519 iterations unroll4
20761 iterations unroll6 ← 2%程度性能向上
20435 iterations unroll8 ← 8 倍以上にはアンロールされない
20422 iterations unr0ll16
X 86はプロセッサがいろいろ頑張りすぎて、
アンロールの有効性は少ないかもしれない。
- 17. きめ細かなチューニングオプション
unroll[n]
アンロールは最適化リファレンス・マニュアルに 83 回も出てくる重要キーワード
ドキュメントで unroll のトレードオフを熱心に説明するわりに、
内部で heuristics に決めてるらしく、 max パラメータしか指定できない。。
- 18. きめ細かなチューニングオプション
optprefetch[n]
自動的に prefetcht0 命令を挿入する最適化
初期値 n=0 なので、意図的に指定する必要あり
PGO では自動的に挿入してくれない
無駄な prefetcht0 は削除してくれる
openjdk7 server JIT コンパイラは
prefetcht0 を自動挿入してくれる
- 19. きめ細かなチューニングオプション
optprefetch[n]
姫野ベンチのようなキャッシュ依存のベンチで効果がある
himenobmtxps.c DSMALL O3 optprefetch[n]
n=0: 5695 MFLOPS
n=2: 6409 MFLOPS 13% 弱向上
ただし、挿入しすぎると性能劣化する
coremark キャッシュによる影響が少ないベンチマーク
n=0 19505 iterations prefetcht0 が 0 命令 O3
n=2 19317 iterations prefetcht0 が 21 命令 O3 optprefetch2
n=4 19157 iterations prefetcht0 が 33 命令 O3 optprefetch4 profuse
n=4 18359 iterations prefetcht0 が 71 命令 O3 optprefetch4
- 20. きめ細かなチューニングオプション
fargument[no]alias
別名の有無を制御するためのオプション
初期値は fargumentalias
別名の制御は一般的に難しいが、 argument は理解しやすい
一般のコンパイラは、下記に示すポインタ A と B が
同じものを指す可能性を考慮して最適化する。
- 21. きめ細かなチューニングオプション
fargument[no]alias
icc で fargumentnoalias を指定すると、
最内側ループのベクトル化を促進
他にも様々な恩恵が
- 22. きめ細かなチューニングオプション
fargument[no]alias
fargumentnoalias は restrict みたいなもの
引数のポインタ同士が同じものを指すことがない
と仮定させるので、結果不正に注意
Aggressive なループ展開と組み合わせると
こんな素敵ループが生成される。
ベクトル化で速くなるとは限らないけど、、
Coremark は fargumentnoalias で 4% 性能向上
19404 iterations fast
20174 iterations fast fargumentnoalias