コードの現代化(最適化) 1-2-3
インテル® コンパイラーを使用する際に直面するよくある問題と課題

2017 年 7 月
iSUS 編集長
すがわら きよふみ© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

このセッションの内容• ベクトル化と命令セット• ベクトル化を支援するコンパイラーの機能• インテル® Advisor を使用した最適化のステップ• 複数ソケットシステム (NUMA) 環境での留意点

このセッションで使用する機材:
インテル® Core™ i7-4790K プロセッサー 4.00GHz (メモリー帯域幅 25.6GB/s) 、インテル® Xeon® プロセッサー E5-2699 v4 2.20GHz

2© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化と命令セット© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ソフトウェアに対するハードウェアの影響
コア数、スレッド数、  ベクトル幅* ark.intel.com で公開されている出荷済の製品仕様

インテル®
インテル® Xeon® インテル® Xeon®
Xeon® プロセッ
プロセッサープロセッサーサー
開発コード名
開発コード名5600 番台
Sandy Bridge EP
Ivy BridgeEP

インテル® Core™
X プロセッサー
開発コード名Skylake-X

インテル®
Xeon Phi™
コプロセッサー開発コード名Knights Cornerインテル® Xeon
Phi™ プロセッサー& コプロセッサー
開発コード
Knights Landing22

6 ~ 18

61

72

36

44

12 ~ 36

244

288

256

256

512

512

512

IMIC

インテル®
AVX512インテル® Xeon® インテル® Xeon®
プロセッサープロセッサー
開発コード名
開発コード名Broadwell EP
Haswell
EP

インテル®
Xeon®
プロセッサー
64 ビットインテル® Xeon®
プロセッサー
5100 番台

インテル®
Xeon® プロセッ
サー5500 番台

コア

1

2

4

6

8

12

18

スレッド

2

2

8

12

16

24

SIMD 幅

128

128

128

128

256

256

インテル® インテル® インテル®
インテル®
SSE3
SSE4.1 SSE4.2
AVX(2004)(2006)(2009) (2010) (2011) (2013)

インテル®
AVX2
(2014) (2016)

インテル®
AVX512(2017)

ハイパフォーマンス・ソフトウェアは両方を活用する必要がある:• 並列性 (マルチスレッド、マルチプロセス) とベクトル化 (SIMD)
4© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

命令セットが拡張されるときに何が起こるのか ?
• SIMD レジスターの幅が同じ場合 (SSE2 -> SSE4.2)−新しい命令や機能をすぐに利用できます• SIMD レジスターの幅が異なる場合 (SSE4.2 -> AVX)
−コンパイラーやプロセッサーが利用できても、OS が新しい命令セットをサポートするのを待つ必要があります… ただし …

SIMD 幅にスケーラブルなコードを作成しておきましょう© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® コンパイラーのベクトル化オプション
自動ベクトル化• /Qax<SIMD 命令セット,…> (-ax<SIMD,…>)• /Qx<SIMD 命令セット> (-x<SIMD>)• /QxHOST (-xHOST)
SIMD 命令セットに指定可能なキーワード:
SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
ATOM_SSSE3, ATOM_SSE4.2,
AVX, CORE-AVX-I, CORE-AVX2,
MIC-AVX512, CORE-AVX512, COMMON-AVX512(128 ビット)(128 ビット)(256 ビット)(512 ビット)/O2 (-O2) 以上が指定されると自動ベクトル化が有効となる:
これらのオプションが指定されない場合のデフォルト命令セットは SSE2
6© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化オプションはパフォーマンスに最も影響する/Qx (-x) と /Qax (-ax)• すべてのソースファイルに同じオプションを指定することを推奨… しかし困難な場合がある …

• オブジェクト・ファイルが提供される、事情によりオプションが制限される

main.cfunc1.cfunc2.obj (または特定のオプションが指示される)> icl main.c func1.c func2.obj /QaxCORE-AVX2 /Fetest_code.exe
または実行すると?
> icl func2.c /QxCORE-AVX512 /c> icl main.c fuinc1.c func2.obj /QaxCORE-AVX2 /Fetest_code.exe
7© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化オプションはパフォーマンスに最も影響する (2)/Qx (-x) と /Qax (-ax)• 問題となる: ターゲットの実行環境が最新のプロセッサーではない、インテル® AVX/AVX2 からインテル® AVX-512 への移行中のコードが含まれる…
必ずしも例外が発生するとは限らない ……
ベクトル化できなければインテル® AVX-512 命令は生成されないコンパイラーのレポートやインテル® Advisor を使用して、ベクトル化されているかどうかを確認
8© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化オプションはパフォーマンスに最も影響する (3)ランタイムチェックの影響> icl multiply.c /c /QaxCORE-AVX512 /QxCORE-AVX2> icl driver.c multiply.obj /QaxCORE-AVX2 /Fedriver.exe> icl multiply.c /c /QxCORE-AVX2> icl driver.c multiply.obj /QaxCORE-AVX2 /Fedriver.exe

処理中に数万回、数十万回呼び出されるような下位の関数では、
ランタイムチェックを行うべきではない
9© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化オプションはパフォーマンスに最も影響する (4)バイナリーに適用されている命令セットは?
ベクトル命令セットにインテル® AVX が適用されている
サーベイレポートで
詳細を確認

10

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

コード中で CPU の命令セットをチェックする#include <immintrin.h>#include <stdio.h>
int main(int argc, char *argv[]) {const unsigned long knl_features =(_FEATURE_AVX512F | _FEATURE_AVX512ER |_FEATURE_AVX512PF | _FEATURE_AVX512CD );if ( _may_i_use_cpu_feature( knl_features ) )printf("This CPU supports AVX-512F+CD+ER+PF as introduced in Knights Landing¥n");else
printf("This CPU does not support all Knights Landing AVX-512 features¥n");return 1;}

インテル® コンパイラーは、プロセッサーの機能をチェックする_may_i_use_cpu_feature() 組込み関数をサポート
https://www.isus.jp/specials/target-intel-core-processors/
https://www.isus.jp/products/c-compilers/how-to-detect-knl-instruction-support/
11© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援する
コンパイラーの機能© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化に影響する 6 つの要因不明なループカウント

ループ伝搬依存DO I = 1, N
A(I+1) = A(I) + B(I)
ENDDO

関数呼び出しfor (i = 1; i < nx; i++) {x = x0 + i * h;sumx = sumx + func(x, y, xp);}

ポインター・エイリアシング

struct _x { int d; int bound; };void doit(int *a, struct _x *x){
for(int i = 0; i < x->bound; i++)a[i] = 0;}

間接メモリーアクセス
for (i=0; i<N; i++)A[B[i]] = C[i]*D[i]外部ループvoid scale(int *a, int *b){for (int i = 0; i < 1000; i++)b[i] = z * a[i];}13for(i = 0; i <= MAX; i++) {for(j = 0; j <= MAX; j++) {D[i][j] += 1;}}© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

さらに ....

ベクトル化を支援するコンパイラー・オプション/Qipo (-ipo)• プロシージャー間の最適化 (IPO) は、マルチステップの自動処理で、コンパイラーがコードを解析してどの最適化が有効であるかを判断できる
ようにしますdouble a[512];
main(){…
func (&a[0], &a[256], ct);…
}

func(double *p,double *q int ct){…
for(i=0; i<ct; i++)p[i] += q[i] * z;…
}

source1.csource2.c

インライン展開およびその他の最適化は、プロファイル情報によって向上
14© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

IPO による最適化
アドレスの解析
配列次元のパディング
エイリアス解析
配列の自動転置
メモリープールの自動生成
C++ クラス階層解析
共通ブロック変数の統合
共通ブロックの分割
定数の伝播
不要な呼び出しの検出
不要な仮引数の排除
不要な関数の排除
仮引数のアライメント解析
前方代入
間接呼び出し変換

15

インライン展開
mod/ref 解析
不要な呼び出しの部分的に排除
レジスターに引数を渡して呼び出しとレジスターの使用を最適化
ポインター解析
ルーチンのキー属性の伝播
専用化
スタックフレームのアライメント
構造体分割とフィールドの並べ替え
シンボル・テーブル・データの促進
未参照変数の削除
プログラム全体の解析© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援するコンパイラーオプション/Qipo (-ipo) 使用時の注意事項• IPO を使用して各ソースファイルがコンパイルされるたびに、コンパイラーはソー
スコードの中間表現 (IR) を擬似オブジェクト・ファイルに格納する。 擬似オブジェク
ト・ファイルには、通常のオブジェクト・ファイルの代わりに IR が含まれる• コンパイラーはリンカーの直前に起動され、コンパイラーは、すべての擬似オブジェ
クト・ファイルを対象に IPO を実行する (.o や .obj にオブジェクトは含まれない)
ipo を適用しないオブジェクトと、ipo を適用したオブジェクトをリンクする場合は、インテルのリンクツールを使用

ライブラリーを作成する場合やリンク時は、lib (ar) や link (ld) の代わりに専用ツール、xilib (xiar) と xilink (xild) を使用する
16© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ipo を適用しないオブジェクトと ipo を適用したオブジェクト

コンパイルされていません。

17© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援するコンパイラーの機能
言語機能 (1)

18

言語機能

説明

__declspec(align(n))

変数を n バイト境界にアライメントするようにコンパイラーに指示する。 変数のアドレス
は address mod n=0__declspec(align(n,off))

各 n バイト境界内でオフセットだけ離して変数を n バイト境界にアライメントするように
コンパイラーに指示する。 変数のアドレスは address mod n=off__assume_aligned(a,n)

配列 a が n バイト境界にアライメントされていると見なすようにコンパイラーに指示する。
アライメント情報が取得できなかった場合に使用する__assume(cond)

このキーワードが指定されている場合は、cond が true であると仮定するようにコンパイ
ラーに指示する。 通常、より効率的なコードを生成するため、アライメント情報のような利用可能な特性をコンパイラーに伝える#pragma ivdep

ベクトル依存性が存在していると推定されてもそれを無視するようにコンパイラーに指示#pragma novector

ループをベクトル化しないように指定© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援するコンパイラーの機能
言語機能 (2)• ソースコードに複数の関数が含まれている場合、アルゴリズムやメモリー参照の方法により、特定の SIMD 命令セットで最適な性能を発揮するような状況を想定してください
func1(){….}
func2(){….}
func3(){….}

インテル® SSE4.2 で最高の性能を発揮!!
> icl source_code.c /QxCORE-AVX-I

source_code.c#pragma [intel] optimization_parameter target_arch=SSE4.2
を関数宣言の直前に追加すると、対象の関数だけ命令セットを変更可能
19© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援するコンパイラーの機能/Qvec- (-no-vec) オプション• ベクトル化によりアプリケーションがどれくらい恩恵を得られているか簡単に調査• /Qvec- (-no-vec) オプションが指定されるとコンパイラーは、
SIMD 命令を使用するが、ベクトル化せずにスカラー操作を行
うコードを生成• /Qvec- (-no-vec) ありと、なしのバイナリーを作成してパフォーマンスを比較

20© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® SSE2

インテル® AVX2

デフォルトの状態を検証
21© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化を支援するコンパイラーの機能
ベクトル化レポート• /Qopt-report (-qopt-report) を指定すると、コンパイラーが適用した、
または適用できなかった最適化に関するレポートを出力
レポート: ループの入れ子、ベクトル、自動並列化の最適化 [loop, vec, par]LOOP BEGIN at C:¥code¥matmul¥multiply.c(13,2)
リマーク #15541: 外部 loop は自動ベクトル化されませんでした: SIMD ディレクティブの使用を検討してください。

LOOP BEGIN at C:¥code¥matmul¥multiply.c(15,3)
リマーク #15344: loop はベクトル化されませんでした: ベクトル依存関係がベクトル化を妨げています。
最初の依存関係を以下に示します。詳細については、レベル 5 のレポートを使用してください。
リマーク #15346: ベクトル依存関係: FLOW の依存関係が b[i] (16:4) と b[i] (16:4) の間に仮定されました。
リマーク #25439: 剰余ありアンロール - 2
LOOP END
LOOP BEGIN at C:¥code¥matmul¥multiply.c(15,3)<Remainder>
LOOP END
LOOP END
22

このレポートは、Visual Studio® 内で利用可能© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

ベクトル化のレポートレベル/Qopt-report:N (-qopt-report=N)
N には、取得するレポートの詳細レベルを指定
N が省略された場合は N = 2 がデフォルト
 レベル 0: ベクトル化レポートなし
 レベル 1: ベクトル化が行われた場合をレポート
 レベル 2: レベル 1 に加え、ベクトル化されなかった場所と簡単な診断をレポート
 レベル 3: ループベクトル化の診断を追加
 レベル 4: データのアライメントなど詳細情報を追加
 レベル 5: 依存性情報を追加

23© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

コンパイラー・レポートのオプション• /Qopt-report-phase:フェーズ[,フェーズ,…]
フェーズ = loop, par, vec, openmp, ipo, pgo, cg, offload, tcollect,all• /Qopt-report-file:stdout | stderr | ファイル名• /Qopt-report-embed• /Qopt-report-routine:<関数名>[,<関数名>]• /Qopt-report-filter: “ソースファイル名, 行番号-行番号”
メッセージを英語にする:/Qdiag-message-catalog- (Windows*)
export LANG=en_US.UTF-8 (Linux*)24© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® Advisor を使用した最適化ステップ••••

現状のコードの状況を知る
最適化の方針を決定する
最適化を適用する
最適化の効果を確認する© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

アプリケーションのパフォーマンスを知る新しい方法
インテル® Advisor の Roofline (ルーフライン) 解析を使用して、デフォルトコードのパフォーマンスを理解する: icl driver.c multiply.c /O2 /Zi

命令セットの潜在的なピーク性能キャッシュとメ
モリーの潜在的なピーク性能

この段階でアプリケーションは、メモリー集約型であり SIMD 命令のロード/ストアデータ
はキャッシュに収まっていないか、活用していないキャッシュを考慮したルーフライン解析のトレーニング: https://www.isus.jp/products/advisor/roofline_webinar/
このセッションで使用する機材: インテル® Core™ i7-4790K プロセッサー 4.00GHz (メモリー帯域幅 25.6GB/s)

26© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

サーベイ解析でさらに詳しく調査••••

ベクトル化されていないスカラーループ
2 回アンロールされている
ループ回数は 50 回
処理全体で 101000000 回呼び出されている

•
•

27

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における
ボトルネックとなっているループ
Intel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

データ型は double
使用されている
レジスターは 3 個

インテル® Advisor による推奨••

28[Recommendations] タブでインテル®
Advisor からの最適化の推奨を得られる[Why No Vectorization?] で詳細を得るにはコンパイラーのレポートが必要© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

-ipo でデフォルトのベクトル化を適用した結果>icl driver.c multiply.c /Qipo /Zi /O2

命令セットの潜在的なピーク性能キャッシュとメ
モリーの潜在的なピーク性能

この段階でアプリケーションの計算性能はかなり向上、L3 キャッシュを効率良く利用しつつある29© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

サーベイ解析でさらに詳しく調査: ipo

•
•
•
•
•

30

インテル® SSE2 でベクトル化されている
セルフ実行時間は、6.914 秒から 1.698 秒へ短縮
11.423 GLOPS
ベクトル化効率 91% で、ベクトル長 2 であるためスカラーに対し 1.82 倍のゲイン
4 回のアンロールに加え、ベクトル化によりループ
回数は 12 回に減少

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® AVX2 命令セットを適用後>icl driver.c multiply.c /Qipo /Zi /O2 /QxCORE-AVX2命令セットの
潜在的なピーク性能

キャッシュとメ
モリーの潜在的なピーク性能インテル® SSE2 でベクトル化されたルーフライン・レポートとほとんど変わらない

31© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

サーベイ解析でさらに詳しく調査: インテル® AVX2

•
•
•
•
•

32

インテル® AVX でベクトル化されている (FMA)
セルフ実行時間は、1.698 秒から 1.499 秒へ短縮
13.479 GLOPS
ベクトル化効率 77% で、ベクトル長 4 であるためスカラーに対し 3.09 倍のゲイン
アンロールは適用されず、ベクトル化によりループ回数は 25 回に減少

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

OpenMP* による並列化を適用後>icl driver.c multiply.c /Qipo /Zi /O2 /QxCORE-AVX2 /Qopenmp

命令セット
の潜在的な
ピーク性能

キャッシュとメ
モリーの潜在的なピーク性能並列化によりキャッシュの利用率は向上し、パフォーマンスもかなり高まっている33© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

サーベイ解析でさらに詳しく調査: OpenMP*

OpenMP* による並列化

スレッド間でループが分割されたことで、スレッド内のループ回数は、6、２、または3。

34© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® AVX-512 命令を含むコード>icl driver.c multiply.c /Qipo /Zi /O2 /QaxCORE-AVX512 /QxCORE-AVX2

インテル® AVX-512 命令は実行されていない

インテル® Advisor は実行されないコードパスのパフォーマンスを推測35© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

インテル® AVX2 とインテル® AVX-512 命令で構成される

複数ソケットシステム (NUMA) 環境での留意点
あなたの開発したコードは、サーバー上で実行されているかもしれません …

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

NUMA 環境でのメモリーアクセス
DRAM

CPU0

QPI

CPU1

DRAM

DRAM

3.
4.

37

CPU1

DRAM

リモート・メモリー・アクセス

ローカル・メモリー・アクセス
1.
2.

CPU0

QPI

CPU0 は CPU0 側の DRAM にデータをリクエスト
CPU0 はデータが存在するか CPU1 に問い合わせ(snoop)
DRAM がデータを返す
CPU1 は問い合わせ (snoop) を返す

1.
2.
3.
4.
5.

CPU0 は CPU1 にデータをリクエスト
リクエストに対し QPI を経由して CPU1 へ
CPU1 の IMC は (CPU1 側の) DRAM にリクエスト
CPU1 はキャッシュ内に問い合わせ (snoops)
データは QPI 経由で CPU0 へ返す

ローカルメモリーの待ち時間は、
このステップまでにかかる待ち時間

リモートメモリーの待ち時間 (レイテンシー) は、
待ち時間の短いインターコネクト次第© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

スレッドのアフィニティー制御と NUMA
DRAM

CPU0

QPI

CPU1

DRAM

NUMA 環境ではスレッドのアフィニティー (配置) がパフォーマンスに影響を及ぼす。
アフィニティーの制御:• numactl コマンドを使用する• KMP_AFFINITY を使用する
2 つのスレッドのアフィニティーを制御する例

スレッド23スレッド
スレッド
スレッド 138

参考文献:
https://www.isus.jp/products/vtune/pu27-03-identify-scalability-problem/
https://www.isus.jp/hpc/optimize-for-numa/© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

まとめ• 最適化の第一歩は、ベクトル化に注目してください• 効率良くベクトル化されたコードは、並列化による相乗効果を高めます• 効率良くベクトル化および並列化されたコードは、将来のハードウェアへの準備を容易にします• 開発ツールも日々進化しています– 最適化ツールを活用しましょう– 新しい機能を使ってみましょう39© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

参考資料
コンパイラー・レポートの例© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (1)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr foo.c
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]
LOOP BEGIN at W:¥sample¥code¥foo.c(4,2)<Multiversioned v1>
remark #25228: データの依存関係のループをマルチバージョンにしました。
remark #15389: ベクトル化のサポート: 参照 theta にアラインされていないアクセスが含まれています。
remark #15389: ベクトル化のサポート: 参照 sth にアラインされていないアクセスが含まれています。
remark #15381: ベクトル化のサポート: ループ本体内でアラインされていないアクセスが使用されました。
remark #15399: ベクトル化のサポート: アンロールファクターが 2 に設定されます。
remark #15417: ベクトル化のサポート: 浮動小数点数をアップコンバートします (単精度から倍精度 1)。
remark #15418: ベクトル化のサポート: 浮動小数点数をダウンコンバートします (倍精度から単精度 1)。
remark #15300: ループがベクトル化されました。
remark #15450: マスクなし非アライン・ユニット・ストライド・ロード: 1#include <math.h>remark #15451: マスクなし非アライン・ユニット・ストライド・ストア: 1
void foo (float * theta, float * sth) {remark #15475: --- ベクトルループのコストサマリー開始 --int i;….
for (i = 0; i < 128; i++)remark #15488: --- ベクトルループのコストサマリー終了 --remark #25015: ループの最大トリップカウントの予測=32
sth[i] = sin(theta[i]+3.1415927);
LOOP END}
LOOP BEGIN at W:¥sample¥code¥foo.c(4,2)<Multiversioned v2>
remark #15304: ループ はベクトル化されませんでした: マルチバージョンのベクトル化できないループ・インスタンスです。
LOOP END

41© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (2)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr /Qalias-args- foo.c

42(Linux* では、-fargument-noalias)
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]
LOOP BEGIN at W:¥sample¥code¥foo.c(4,2)
remark #15389: ベクトル化のサポート: 参照 theta にアラインされていないアクセスが含まれています。
remark #15389: ベクトル化のサポート: 参照 sth にアラインされていないアクセスが含まれています。
remark #15381: ベクトル化のサポート: ループ本体内でアラインされていないアクセスが使用されました。
remark #15399: ベクトル化のサポート: アンロールファクターが 2 に設定されます。
remark #15417: ベクトル化のサポート: 浮動小数点数をアップコンバートします (単精度から倍精度 1)。
remark #15418: ベクトル化のサポート: 浮動小数点数をダウンコンバートします (倍精度から単精度 1)。
remark #15300: ループがベクトル化されました。
remark #15450: マスクなし非アライン・ユニット・ストライド・ロード: 1
remark #15451: マスクなし非アライン・ユニット・ストライド・ストア: 1
remark #15475: --- ベクトルループのコストサマリー開始 --remark #15476: スカラーループのコスト: 114#include <math.h>remark #15477: ベクトルループのコスト: 40.750
void foo (float * theta, float * sth) {remark #15478: スピードアップの期待値: 2.790
int i;
remark #15479: 低オーバーヘッドのベクトル操作: 9for (i = 0; i < 128; i++)remark #15480: 中オーバーヘッドのベクトル操作: 1
remark #15481: 高オーバーヘッドのベクトル操作: 1
sth[i] = sin(theta[i]+3.1415927);
remark #15482: ベクトル化された算術ライブラリーの呼び出し: 1}
remark #15487: 型変換: 2
remark #15488: --- ベクトルループのコストサマリー終了 --remark #25015: ループの最大トリップカウントの予測=32
LOOP END© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (3)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr /Qalias-args- foo2.c
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]
LOOP BEGIN W:¥sample¥code¥foo2.c(4,2)
remark #15389: ベクトル化のサポート: 参照 theta にアラインされていないアクセスが含まれています。
remark #15389: ベクトル化のサポート: 参照 sth にアラインされていないアクセスが含まれています。
remark #15381: ベクトル化のサポート: ループ本体内でアラインされていないアクセスが使用されました。
remark #15300: ループがベクトル化されました。
remark #15450: マスクなし非アライン・ユニット・ストライド・ロード: 1
remark #15451: マスクなし非アライン・ユニット・ストライド・ストア: 1
remark #15475: --- ベクトルループのコストサマリー開始 --remark #15476: スカラーループのコスト: 111#include <math.h>remark #15477: ベクトルループのコスト: 20.500
void foo (float * theta, float * sth) {remark #15478: スピードアップの期待値: 5.400
int i;
remark #15479: 低オーバーヘッドのベクトル操作: 8for (i = 0; i < 128; i++)remark #15481: 高オーバーヘッドのベクトル操作: 1
sth[i] = sinf(theta[i]+3.1415927f);
remark #15482: ベクトル化された算術ライブラリーの呼び出し: 1}
remark #15488: --- ベクトルループのコストサマリー終了 --remark #25015: ループの最大トリップカウントの予測=32
LOOP END
43© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (4)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr /Qalias-args- /Qxavx foo2.c
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]
LOOP BEGIN at W:¥sample¥code¥foo2.c(4,2)
remark #15389: ベクトル化のサポート: 参照 theta にアラインされていないアクセスが含まれています。
remark #15389: ベクトル化のサポート: 参照 sth にアラインされていないアクセスが含まれています。
remark #15381: ベクトル化のサポート: ループ本体内でアラインされていないアクセスが使用されました。
remark #15300: ループがベクトル化されました。
remark #15450: マスクなし非アライン・ユニット・ストライド・ロード: 1
remark #15451: マスクなし非アライン・ユニット・ストライド・ストア: 1
remark #15475: --- ベクトルループのコストサマリー開始 --#include <math.h>remark #15476: スカラーループのコスト: 110
void foo (float * theta, float * sth) {remark #15477: ベクトルループのコスト: 11.620
int i;
remark #15478: スピードアップの期待値: 9.410
remark #15479: 低オーバーヘッドのベクトル操作: 8for (i = 0; i < 128; i++)remark #15481: 高オーバーヘッドのベクトル操作: 1
sth[i] = sinf(theta[i]+3.1415927f);
remark #15482: ベクトル化された算術ライブラリーの呼び出し: 1}
remark #15488: --- ベクトルループのコストサマリー終了 --remark #25015: ループの最大トリップカウントの予測=16
LOOP END
44© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (5)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr /Qalias-args- /Qxavx foo3.c
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]

LOOP BEGIN W:¥sample¥code¥foo3.c(6,2)
remark #15388: ベクトル化のサポート: 参照 theta にアラインされたアクセスが含まれています。
remark #15388: ベクトル化のサポート: 参照 sth にアラインされたアクセスが含まれています。
remark #15300: ループがベクトル化されました。
remark #15448: マスクなしアライン・ユニット・ストライド・ロード: 1
remark #15449: マスクなしアライン・ユニット・ストライド・ストア: 1
remark #15475: --- ベクトルループのコストサマリー開始 --remark #15476: スカラーループのコスト: 110#include <math.h>remark #15477: ベクトルループのコスト: 9.870
void foo (float * theta, float * sth) {remark #15478: スピードアップの期待値: 11.130
int i;
remark #15479: 低オーバーヘッドのベクトル操作: 8__assume_aligned(theta,32);
remark #15481: 高オーバーヘッドのベクトル操作: 1__assume_aligned(sth,32);
remark #15482: ベクトル化された算術ライブラリーの呼び出し: 1for (i = 0; i < 128; i++)remark #15488: --- ベクトルループのコストサマリー終了 --sth[i] = sinf(theta[i]+3.1415927f);
remark #25015: ループの最大トリップカウントの予測=16}
LOOP END

45© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

レポートへの対応例 (6)$ icl /c /Qopt-report:4 /Qopt-report-phase:loop,vec /Qopt-report-file:stderr /Qalias-args- /Qxavx foo4.c
最適化レポート開始: foo(float *, float *)レポート: ループの入れ子、ベクトルの最適化 [loop, vec]
LOOP BEGIN W:¥sample¥code¥foo4.c(6,2)
remark #15388: ベクトル化のサポート: 参照 theta にアラインされたアクセスが含まれています。
remark #15388: ベクトル化のサポート: 参照 sth にアラインされたアクセスが含まれています。
remark #15412: ベクトル化のサポート: sth のストリーミング・ストアが生成されました。
remark #15300: ループがベクトル化されました。
remark #15448: マスクなしアライン・ユニット・ストライド・ロード: 1
remark #15449: マスクなしアライン・ユニット・ストライド・ストア: 1#include <math.h>remark #15467: マスクなしアライン・ストリーミング・ストア: 1
void foo (float * theta, float * sth) {remark #15475: --- ベクトルループのコストサマリー開始 --int i;
remark #15476: スカラーループのコスト: 110__assume_aligned(theta,32);
remark #15477: ベクトルループのコスト: 9.870
remark #15478: スピードアップの期待値: 11.130__assume_aligned(sth,32);
remark #15479: 低オーバーヘッドのベクトル操作: 8for (i = 0; i < 2000000; i++)remark #15481: 高オーバーヘッドのベクトル操作: 1
sth[i] = sinf(theta[i]+3.1415927f);
remark #15482: ベクトル化された算術ライブラリーの呼び出し: 1}
remark #15488: --- ベクトルループのコストサマリー終了 --remark #25015: ループの最大トリップカウントの予測=250000
LOOP END
46© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

iSUS の参考記事• インテルのベクトル化ツール

https://www.isus.jp/intel-vectorization-tools/• インテル® Advisor 2017 ツールによるベクトル化のクイック解析

https://www.isus.jp/products/advisor/quick-analysis-of-vectorization-using-advisor-2017-tool/• 一般的なベクトル化のヒント

https://www.isus.jp/products/c-compilers/common-vectorization-tips/• インテル® AVX-512 で向上したベクトル化のパフォーマンス

https://www.isus.jp/products/psxe/pu27-04-vectorization-opportunities/• 自動ベクトル化が失敗した場合の対処

https://www.isus.jp/products/c-compilers/what-to-do-when-auto-vectorization-fails/• ベクトル化されたリダクション操作を記述できますか?

https://www.isus.jp/products/c-compilers/can-you-write-vectorized-reduction-operation/
https://www.isus.jp/products/c-compilers/vectorized-reduction-2-let-the-compiler-do/• 間接呼び出しと仮想関数の呼び出し: インテル® C/C++ コンパイラー 17.0 によるベクトル化
https://www.isus.jp/products/psxe/pu25-06-indirect-calls-and-virtual-functions-calls/• ループをベクトル化するための条件

https://www.isus.jp/products/psxe/requirements-for-vectorizable-loops/© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。

© 2017 iSUS. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国におけるIntel Corporation の商標です。*その他の社名、製品名などは、一般に各社の商標または登録商標です。