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