キャッシュヒントの自動付加による 数値計算の高速化 早稲田大学 理工学研究科 情報・ネットワーク専攻 稲垣 良一 1 / 48 <[email protected]> 概要 プロセッサの性能を最大限に活かしたソフトウェアを作成 するためには、キャッシュの有効活用が不可欠である. Itanium プロセッサに搭載されているキャッシュヒント機 能は、適切に使用することでキャッシュ有効活用への期 待が持てるが,既存のコンパイラはキャッシュヒントを使 用したプログラムを生成しない. 本発表では Itanium プロセッサのキャッシュヒントを紹介 し,既存のコンパイラを使用してキャッシュヒントを自動的 に付加する手法について述べる.また,FFT などの数値 計算に対してキャッシュヒントを付加した場合の性能評価 についても紹介する. 2005/7/29 2 / 48 背景 – ハードウェアの性能向上 計算機の性能は向上を続けている プロセッサ周波数、メモリ帯域、etc ・・・ しかし、プロセッサとメモリの速度差は拡大 2年で2倍のペース メモリアクセスコストは相対的に増加 プロセッサの性能を活かしたソフトウェアの構築 一般的な対処方法 メモリアクセス遅延の隠蔽 キャッシュの有効活用 メモリアクセスコストの 相対的な増加 2005/7/29 3 / 48 目次 背景 キャッシュの有効活用 Itanium プロセッサのキャッシュヒント キャッシュヒントの自動付加手法 キャッシュヒント付加時の性能評価 2005/7/29 4 / 48 キャッシュ Itanium2 Processor 1.4GHz の場合 slow fast Itanium2 Processor Main Memory L3: 3 MB Line Size: 128 Byte Latency: 12~13 cycle L2: 256 KB Line Size: 128 Byte Latency: 5~6 cycle Latency: 100~ cycle キャッシュ階層間帯域:32GB/s キャッシュ・メモリ間帯域:6.4GB/s L1D: 16 KB Line Size: 64 Byte Latency: 1 cycle 2005/7/29 5 / 48 例:行列積の計算 for(i=0; i<L; i++){ for(j=0; j<N; j++){ for(k=0; k<M; k++){ z[i][j] += x[i][k] * y[k][j]; } } Z=X*Y } N M = L × L Z X 2005/7/29 6 / 48 N M Y 例:行列積の計算 特に工夫しないプログラムの性能 • 行列サイズが 512 以上 で性能が急落する • 特定の行列サイズでも 性能が低下 2005/7/29 7 / 48 メモリアクセスコストを抑える具体的手法 Itanium プロセッサの機能 キャッシュの有効活用 キャッシュヒント 後述 メモリアクセス遅延の隠蔽 命令スケジューリング アドバンスト・ロード プリフェッチ(ハードウェア) コンパイラががんばる ソフトウェアレベルでの工夫 キャッシュの有効活用 データレイアウトの改善 データの再配置 配列に対するブロッキング、パディング 計算順序の変更 プログラマががんばる コンパイラもがんばる ループ変換、結合 メモリアクセス遅延の隠蔽 プリフェッチ(ソフトウェア) 2005/7/29 8 / 48 例:行列積の計算 データレイアウトの改善 行列の転置 N L M = L M × N Y(転置) 行列のブロッキング = 2005/7/29 9 / 48 × 例:行列積の計算 行列の転置 約10倍 2005/7/29 10 / 48 例:行列積の計算 行列の転置+ブロッキング 2005/7/29 11 / 48 キャッシュの有効活用 ソフトウェアレベルでの工夫 キャッシュを意識したプログラミングは重要 ソフトウェアの構築コスト大 プログラムごと、計算機ごとに検討 キャッシュサイズが異なれば、最適なブロッキングのサイズも異なる ボトルネックの解析 プロファイラ (gprof, VTune) コンパイラの最適化機能 数値計算ライブラリ プロセッサ、キャッシュに対して最適化 Intel Math Kernel Library, AMD Core Math Library ATLAS, FFTE, FFTW 2005/7/29 12 / 48 キャッシュヒント 13 / 48 キャッシュヒント キャッシュ有効活用のための一機能 キャッシュの制御をソフトウェアレベルで実現す るための仕組み ⇔ 従来はハードウェアレベルでの制御 「どのキャッシュ階層」に「どのようにデータを配置」するか 取り込むキャッシュ階層 LRU bit の更新 メモリアクセス命令単位で適用可能 データの局所性を意識したキャッシュの有効活用 多段キャッシュの有効活用 プログラムの振る舞いには影響を与えない 2005/7/29 14 / 48 キャッシュヒントの振る舞い 通常のストア命令によるキャッシュの変化 .nta ヒントを付加したストア命令によるキャッシュの変化 cf. ストリーミングストア (Pentium3~) 2005/7/29 15 / 48 Itanium プロセッサのキャッシュヒント Itanium プロセッサのキャッシュヒント 全部で4種類 .t1, .nt1, .nt2, .nta 通常のメモリアクセス命令にヒントを付加する形で実現 Itanium 命令のコンプリケータ ストア命令、ロード命令、プリフェッチ命令 例) st8 → st8.nta, ld4 → ld4.nt1, lfetch → lfetch.nt2 cf. Pentium 系プロセッサのキャッシュヒント プリフェッチ命令のみヒントを指定できる(異なる命令) prefetcht0, prefetcht1, prefetcht2, prefetchnta 2005/7/29 16 / 48 キャッシュヒントの種類と振る舞い インテル® Itanium®2 プロセッサ リファレン ス・マニュアル より引 用 2005/7/29 17 / 48 .nta ヒント .nta ヒント (Non-Temporal locality in All levels) データを L2 キャッシュにのみ配置 キャッシュの LRU bit を更新しない ⇒ データをキャッシュ内に最も残さないヒント .nta ヒントの有用性 1度使うだけで再利用のないメモリアクセスをキャッ シュに残さない 他の再利用される(かもしれない)データがキャッシュ から追い出されにくくなる ⇒ キャッシュヒット率の向上 2005/7/29 18 / 48 .nta ヒントの振る舞い 通常のストア命令によるキャッシュの変化 .nta ヒントを付加したストア命令によるキャッシュの変化 cf. ストリーミングストア (Pentium3~) 2005/7/29 19 / 48 キャッシュヒントとコンパイラ 現状 既存のコンパイラはキャッシュヒント を使用したコードを生成しない! Intel Compiler GCC で確認 2005/7/29 20 / 48 キャッシュヒントとコンパイラ コンパイラがキャッシュヒントを使用しない理由? 性能低下の可能性 キャッシュヒントの選択次第では、本来キャッシュに残ってい て欲しいデータを残さないようにすることもできる → キャッシュヒット率低下の可能性 触らぬ神に祟りなし ハードウェアのキャッシュ制御に任せる ヒントの選択が難しい? 命令スケジューリング≫キャッシュヒント? Itanium では命令スケジューリングが性能を最も左右 2005/7/29 21 / 48 キャッシュヒントとコンパイラ それでもキャッシュヒントを使いたい ハードウェアに実装されている機能を使い切っていな いのは勿体無い(←貧乏性?) キャッシュヒントを使用する方法があってもいいのでは? キャッシュヒントの付加についての先行研究 Beyls (Gent Univ) らの研究 K.Beyls and E.D'Hollander. Compile-Time Cache Hint Generation for EPIC Architectures, In Proc. EPIC2, pp.19--29, Nov 2002. Reuse Distance という尺度に基づいてキャッシュヒントを選択 することで、ソフトウェアの性能が向上する場合がある Open Research Compiler 上に実装・・・ 2005/7/29 22 / 48 キャッシュヒントとコンパイラ 既存のコンパイラにキャッシュヒント付加機能を 付加できないだろうか? キャッシュヒント自動付加手法へ 2005/7/29 23 / 48 キャッシュヒントの自動付加手法 24 / 48 キャッシュヒントの自動付加手法 Source Program (C, C++, Fortran, etc…) Binary Program Compiler/Assembler/Linker Assembly Program Assembly Program (annotated Cachehint) Cachehint Annotation Unit (CHSU-core) ・・・ CacheHint Supply Utility (CHSU) 従来のコード生成 ・・・ 提案する手法 2005/7/29 25 / 48 本手法の特徴 1. プログラミング言語に依存しない アセンブリプログラムを生成できるコンパイラがあれば、本手法 は適用可能 使用するコンパイラも選択可能 2. 自動実行 既存のコンパイラのラッパーとして動作 $ icc –O3 –o foo foo.c Intel Compiler の場合 $ chsu –O3 –o foo foo.c 本手法の場合 既存のコンパイラの最適化機能を活かした上で、キャッシュヒン トを付加 2005/7/29 26 / 48 CHSUの設計・実装 Java で実装 Source Program フロントエンド CHSU-core Compiler/Assembler/Linker Assembly Program フロントエンド コマンドラインの解析 ファイル、オプション Binary Program Assembly Program (annotated Cachehint) Cachehint Annotation Unit (CHSU-core) 設定ファイルの解析 プログラミング言語(拡張子)と使用するコンパイラ、アセンブ ラの関連付け コンパイラ、アセンブラを外部プロセスとして起動 アセンブリプログラムを CHSU-core に渡す 2005/7/29 27 / 48 CHSUの設計・実装 CHSU-core Source Program アセンブリプログラムの 解析 キャッシュヒントの付加 キャッシュヒント付加済 プログラムの出力 Binary Program Compiler/Assembler/Linker Assembly Program 字句解析 アセンブリプログラムの構造を抽出 2005/7/29 28 / 48 (annotated Cachehint) Cachehint Annotation Unit アセンブリプログラムの解析 Assembly Program (CHSU-core) アセンブリプログラムの解析 3種類のデータ構造 Program プログラム Procedure Block Procedure Block Block アセンブリプログラム中のラベルで 区切られる部分 (Procedure内) ディレクティブ等、解析上関係ない 部分 (Procedure外) Program Block プロシージャ(関数) Block Procedure 外の Block は以降の 解析では無視する 2005/7/29 29 / 48 Block Block Block Block Block Procedure アセンブリプログラムの解析 Block の区切り方 ..... nop.i 0 ;; ラベルを基準に区切る Block が保持する情報 アセンブリプログラム原文 Block のラベル名 命令の種類・数 分岐命令の分岐先 br.call, br.ret 以外 実行サイクル数 命令、ストップの数で判断 } label_a: { .mmi (p17) add r35=0x100, r0 (p17) add r32=-1,r33 (p17) add r39=65474,r0 } ..... ..... ..... { .bbb (p7) br.cond.dptk.many label_i (p9) br.cond.dptk label_j br.cond.sptk label_k } label_b: { .mmi ..... 2005/7/29 30 / 48 キャッシュヒントの付加方針 .nta ヒント・・・1度使うだけで再利用しないメモリアクセスに有効 再利用しない(再利用しなそうな)メモリアクセス命令をアセンブリ プログラム中から発見して、ヒントを付加すればよい 本研究での方針・・・プログラムの局所性に注目 (数値計算を含む)多くのソフトウェアは、データのストア・ロード のほとんどを for ループなどの局所性が高い部分で実行 メモリアクセスの振る舞いを仮定 キャッシュヒント付加の基準に for(i=0; i<L; i++){ z[i] = x[i] * y[i]; } store 2005/7/29 31 / 48 load load キャッシュヒントの付加方針 局所性の高い部分のメモリアクセス命令 ストア命令 同じメモリアドレスにデータを何度もストアすることはない ⇒再利用しないメモリアクセス命令と仮定 ロード命令 同じメモリアドレスからデータを何度もロードすることはない しかし、同じキャッシュライン上にある別のメモリアドレスから データがロードされる可能性はある ⇒キャッシュラインが再利用される ⇒再利用されるメモリアクセス命令と仮定 for(i=0; i<L; i++){ z[i] = x[i] * y[i]; } store 2005/7/29 32 / 48 load load キャッシュヒントの付加方針 局所性の低い部分のメモリアクセス命令 他の部分に比べて実行回数が相対的に少ない ⇒再利用しないメモリアクセス命令と仮定 プログラムの局所性と.nta ヒント付加の関係 局所性の高い部分 局所性の低い部分 ストア命令 ○ ○ ロード命令 × ○ どちらにも該当しなければ、ヒントは付加しない 2005/7/29 33 / 48 キャッシュヒント付加の実装 アセンブリプログラムの解析 Procedure 単位で処理 Block が保持している情報を利用 分岐命令の分岐先 ① プログラムのループ構造 自Blockへの分岐を持つ Block ループ構造そのもの for文, while文がアセンブリプログラムに なった形であると考えられる Block の局所性が高いと判断 → ストア命令に .nta ヒントを付加する 2005/7/29 34 / 48 label_a: … br label_p … label_b: … br label_b キャッシュヒント付加の実装 ② リターン命令 プロシージャ・リターン命令(br.ret) を持つ Block は Procedure 内で最後に実行される 繰り返し実行される可能性は少ない Block の局所性が低いと判断 → ストア命令・ロード命令に .nta ヒントを付加する 2005/7/29 35 / 48 label_q: … br.ret label_r: … キャッシュヒント付加の実装 キャッシュヒントの付加 Block が保持しているプログラム原文を書き換える 対象となるメモリアクセス命令の語尾に .nta を付加 { .mmi (p16) lfetch.nt1 (p18) stfd.nta stfd (p16) add } { .mmi (p18) stfd.nta stfd (p18) stfd.nta stfd (p16) add } [r34] [r9]=f61,64 r45=64,r46;; [r8]=f68,64 [r3]=f60,64 r32=128,r34 2005/7/29 36 / 48 label_b: … br label_b 評価 37 / 48 評価環境・内容 評価環境 – SGI Altix 350 Itanium2 1.4GHz L1D:16KB, L2:256KB, L3:3MB 使用コンパイラ Intel Compiler 8.1, GCC 3.2.3 数値計算ソフトウェアにキャッシュヒント付加を適用 FFTE 4.0 FFT ライブラリ、キャッシュ内での高速な動作 行列積計算 ATLAS 3.6.0 手書きの行列積計算 NPB 3.2 NAS Parallel Benchmark 2005/7/29 38 / 48 評価(1) – FFTE 4.0 1次元FFT データサイズを変化させて性能を測定 キャッシュヒントの有無による性能を比較 ストア命令にのみ, ロード命令にのみ, 両方 15%性能向上 120 性能向上率 (%) 115 110 105 100 95 90 14 15 16 17 18 19 20 FFT データ数 (2^m) Itanium2 L3上限 Store Hint Load Hint 2005/7/29 39 / 48 Store & Load Hint 21 22 23 評価(1) – FFTE 4.0 N=217 Original w/Cache Hint L2 cache hit 0.981 0.982 L3 cache hit 0.401 0.551 IPC 1.703 1.754 Total stalls 0.625 0.605 プロセッサイベントの計測 15% perfmon 結果から L3 キャッシュヒット率の向上 N=217の場合で15% N=220 Original w/Cache Hint L2 cache hit 0.979 0.979 L3 cache hit 0.331 0.337 IPC 1.541 1.570 Total stalls 0.668 0.662 2005/7/29 40 / 48 IPC の向上 Total stalls の減少 評価(1) – FFTE 4.0 m≧17 以降、性能は向上しているが、その向上率は小さくなっている FFTE 内で使用する全データサイズに対する L3 キャッシュの割合が小 さくなっていくため、.nta ヒント付加の効果の割合も小さくなっている 120 性能向上率 (%) 115 110 105 100 95 90 14 15 16 17 18 19 20 FFT データ数 (2^m) Itanium2 L3上限 Store Hint Load Hint 2005/7/29 41 / 48 Store & Load Hint 21 22 23 評価(2) – 行列積計算 ATLAS 3.6.0 自動チューニング機構を持つ数値計算ライブラリ MFLOP ベースで 1%~2% の性能向 上 2005/7/29 42 / 48 評価(2) – 行列積計算 手書きの行列積計算 Q: キャッシュを有効に使っていない、効率の悪いプログラムに対し てもキャッシュヒント付加は有効か? 2005/7/29 43 / 48 評価(3) – NPB 3.2 NAS Parallel Benchmark 並列計算機用のベンチマーク集 今回使用したのは逐次実行版(NPB-SER) 性能向上率(%) 120 110 100 90 80 70 EP MG CG FT Class W 2005/7/29 44 / 48 IS Class A LU SP BT 評価(3) – NPB 3.2 CG Original w/Cache Hint L2 cache hit 0.957 0.957 L3 cache hit 0.044 0.047 IPC 0.779 0.616 Total stalls 0.857 0.886 Original w/Cache Hint L2 cache hit 0.958 0.968 L3 cache hit 0.338 0.332 IPC 0.865 0.886 Total stalls 0.735 0.727 (Class W) IS (Class W) 2005/7/29 45 / 48 プロセッサイベントの計測 キャッシュヒント付加に関する考察 現在のキャッシュヒント付加方針 性能が上がるもの、下がるもの共に存在 よくチューニングされているプログラムの方が、性能が向上し ている傾向がある 今後、キャッシュヒント付加方針の種類を増やしたい .nta ヒントの付加による性能向上 L3 キャッシュのヒット率向上 プロセッサに載る L3 キャッシュは増量傾向 ⇒ ヒット率の向上は有効! 2005/7/29 46 / 48 まとめ 以下の内容について紹介した キャッシュの有効活用 Itanium プロセッサのキャッシュヒント キャッシュヒントの自動付加手法、CHSU 自動実行、汎用性の高い手法 キャッシュヒント付加時の性能評価 FFT で最高15%の性能向上 .nta ヒントの付加による L3 キャッシュのヒット率向上 2005/7/29 47 / 48 まとめ CHSUの今後 キャッシュヒント付加方針の検討・充実 性能評価の充実 バイナリプログラムへの適用 逆アセンブルなどを行えば可能? CHSU の実装 http://www.ueda.info.waseda.ac.jp/~inagaki/chsu/ で、近日公開(予定) 2005/7/29 48 / 48
© Copyright 2024 ExpyDoc