x86opti01 nothingcosmos

22
本物の X86Optimizer icc を使う Outline 1. X86 なら icc だよね! 2. コンパイラと協調した最適化 3. 各種オプションの詳細 2011/08/06 X86/X64 最適化勉強会 1 nothingcosmos <[email protected]>

Upload: nothingcosmos

Post on 28-May-2015

2.323 views

Category:

Documents


4 download

DESCRIPTION

X86/X64最適化勉強会での紹介資料コンパイラ系の簡単な紹介

TRANSCRIPT

Page 1: X86opti01 nothingcosmos

本物の X86Optimizer はicc を使う

Outline

1. X86 なら icc だよね!

2. コンパイラと協調した最適化

3. 各種オプションの詳細2011/08/06 X86/X64 最適化勉強会 1

nothingcosmos <[email protected]>

Page 2: X86opti01 nothingcosmos

プロフィール

HN:nothingcosmos コンパイラ屋歴 6 年くらい

X86 アセンブリプログラミング経験は少なめ

X86 を最適化する上で、

コンパイラと上手に付き合うための方法を紹介

決して Intel の回し者ではありませんので、、

Page 3: X86opti01 nothingcosmos

X86 なら ICC だよね!

Linux 版の IntelCompiler およびライブラリは

非商用において、無償でつかえる

Linux 版URL:http://goo.gl/nOeTP

今回の資料は、 Intel Composer XE 2011

最適化クイック・リファレンス・ガイド

をちょっと掘り下げています。

Page 4: X86opti01 nothingcosmos

icc のコンパイルオプション Icc に一番速いやつで頼むオプションは、 ­fast

­fast = ­xHOST ­O3 ­ipo ­no­prec­div ­static

xHOST : ホストで最速な命令セットを使用する

O3 : speed 最優先のアグレッシブな最適化

ipo : プロシージャ間の最適化

no­prec­div: 浮動小数点精度の向上

static : 共有ライブラリを使用せず、内部に取り込む

Page 5: X86opti01 nothingcosmos

コンパイラと協調した最適化

コンパイラオプションでチューニングする

プロシージャ間の最適化 プロファイルに基づいた最適化 きめ細やかなチューニングオプション

pragma directive 等の使用 手でボトルネック部分を最適化する

コンパイラのレポート機能の活用

Vtune などのパフォーマンスアナライザの活用 SIMD 等のアセンブリプログラミング

手軽

効果高い

Page 6: X86opti01 nothingcosmos

コンパイラと協調した最適化

コンパイラオプションでチューニングする

プロシージャ間の最適化 プロファイルに基づいた最適化 きめ細やかなチューニングオプション

手軽

効果高い

コンパイラ担当なので、コンパイラオプションの紹介をします

ハンドオプティマイズやSIMDアセンブリプログラミングなんかは他の方が紹介してくれるそうなので

Page 7: X86opti01 nothingcosmos

ここからオプションの詳細

プロシージャ間の最適化 (IPO) プロファイルに基づいた最適化 (PBO) きめ細やかなチューニングオプション

ループアンローリング ソフトウェアプリフェッチ エイリアシング

既にご存知の方はどのくらい???

Page 8: X86opti01 nothingcosmos

プロシージャー間の最適化

複数ファイルに跨った最適化を有効にする

複数ファイルのコンパイル時に効果を発揮する

別ファイルの関数の inline 展開、メモリレイアウトの改善

別名解析の精度向上、不要なシンボルの除去に伴うプログラムサイズの改善

複数ファイルをコンパイルする coremark で性能測定

20297 iterations ­O3 ­xHOST ­fargument­noalias

20533 iterations ­O3 ­xHOST ­fargument­noalias ­ipo

Page 9: X86opti01 nothingcosmos

プロシージャー間の最適化

普通のコンパイルプロセス

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

プロシージャー間の最適化

JVM は必要なクラスを全て取り込んだ状態で JIT コンパイルするので

プロシージャ間と考え方は同じ。

積極的に inline 展開や脱仮想化を試行できる

classloader が上記を阻害するけど、脱最適化と再コンパイルで回避

IPO や LTO の注意点として

llvm(­O4, std­link­opts, ­internalize) は、

1 つの実行ファイルとして仮定して最適化し、シンボルの static 化を行う。

他からの参照があると、 ld で見つからないことも。。

Page 11: X86opti01 nothingcosmos

プロファイルに基づく最適化

プロファイル情報を使用してさらに高度な最適化を行う

使うためには、 3 段階の手順が必要

1. $ icc ­prof­gen ­O0 xxx.c 関数の埋め込み

2. $ ./a.out プロファイル情報の収集

3. $ icc ­prof­use ­fast xxx.c 最適化を有効化

Coremark も性能向上。ほんのちょっと。

19404 iterations ­fast

19531 iterations ­fast ­prof­use

20567 iterations ­fast ­fargument­noalias

21398 iterations ­fast ­fargument­noalias ­prof­use 4% 性能向上

Page 12: X86opti01 nothingcosmos

プロファイルに基づく最適化 ­prof­gen を指定すると、関数の入口

出口、分岐に命令を埋め込む

関数やブロックの実行回数、

分岐確率等をファイルに記録し、

最適化に活かすことができる。

JVM はインタプリタ実行時に取得

↓llvm 的にはこんな感じ

Page 13: X86opti01 nothingcosmos

プロファイルに基づく最適化

PGO の利点

分岐予測の最適化が改善される。マニュアルの 3.4.1 過度なループ展開、ベクトル化、プリフェッチの抑止

細かい最適化テクニックを駆使するよりも、

PGO に任せた方がよい。

プロファイルのパラメータと異なる場合、性能劣化の可能性

プロファイル結果に敏感なコンパイラの場合は注意

icc はあまり劣化するようなことはしないが、

java ­server コンパイラなんかは積極的に活用します

Page 14: X86opti01 nothingcosmos

きめ細かなチューニングオプション

インテル ComposerXE2011

最適化クイック・リファレンス・ガイドより

­unroll[n] ­opt­prefetch[n] ­fargument­[no]alias

Page 15: X86opti01 nothingcosmos

きめ細かなチューニングオプション­unroll[n]

ループ展開の最大数 n を指定する。 0 で展開無効化

ループを n 倍展開すると、様々な恩恵を得て性能向上

やりすぎると様々なキャッシュがオーバーして性能劣化

個人的には、しきい値の調整は PGOに任せればいいんじゃないかと思ってます。

Page 16: X86opti01 nothingcosmos

きめ細かなチューニングオプション­unroll[n]

ループ展開の効果を coremark で測定

共通オプション ­fast ­fargument­noalias

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

きめ細かなチューニングオプション­unroll[n]

アンロールは最適化リファレンス・マニュアルに 83回も出てくる重要キーワードドキュメントで unrollのトレードオフを熱心に説明するわりに、内部で heuristicsに決めてるらしく、maxパラメータしか指定できない。。

Page 18: X86opti01 nothingcosmos

きめ細かなチューニングオプション­opt­prefetch[n]

自動的に prefetcht0 命令を挿入する最適化

初期値 n=0 なので、意図的に指定する必要あり

PGO では自動的に挿入してくれない

無駄な prefetcht0 は削除してくれる

openjdk7 ­server  JIT コンパイラは

prefetcht0 を自動挿入してくれる

Page 19: X86opti01 nothingcosmos

きめ細かなチューニングオプション­opt­prefetch[n]

姫野ベンチのようなキャッシュ依存のベンチで効果がある

himenobmtxps.c ­DSMALL ­O3 ­opt­prefetch[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 ­opt­prefetch2

n=4 19157 iterations prefetcht0 が 33 命令 ­O3 ­opt­prefetch4 ­prof­use

n=4  18359 iterations prefetcht0 が 71 命令 ­O3 ­opt­prefetch4

Page 20: X86opti01 nothingcosmos

きめ細かなチューニングオプション­fargument­[no]alias

別名の有無を制御するためのオプション

初期値は ­fargument­alias

別名の制御は一般的に難しいが、 argument は理解しやすい

一般のコンパイラは、下記に示すポインタ A と B が

同じものを指す可能性を考慮して最適化する。

Page 21: X86opti01 nothingcosmos

きめ細かなチューニングオプション­fargument­[no]alias

icc で ­fargument­noalias を指定すると、

最内側ループのベクトル化を促進

他にも様々な恩恵が

Page 22: X86opti01 nothingcosmos

きめ細かなチューニングオプション­fargument­[no]alias

­fargument­noalias は restrict みたいなもの

引数のポインタ同士が同じものを指すことがない

と仮定させるので、結果不正に注意

Aggressive なループ展開と組み合わせると

こんな素敵ループが生成される。

ベクトル化で速くなるとは限らないけど、、

Coremark は ­fargument­noalias で 4% 性能向上

19404 iterations ­fast

20174 iterations ­fast ­fargument­noalias