Upgrade to Pro — share decks privately, control downloads, hide ads and more …

メモリボトルネックの概要とその影響について - CADDi STUDDi

E55fbffb4afd0a84d36c945ed68d8c19?s=47 CADDi
December 10, 2021
520

メモリボトルネックの概要とその影響について - CADDi STUDDi

E55fbffb4afd0a84d36c945ed68d8c19?s=128

CADDi

December 10, 2021
Tweet

Transcript

  1. メモリボトルネックの概要と その影響について

  2. 今日話すこと • 自己紹介 • CPUの性能とメモリ性能の関係 • 行列行列積に見るCPUキャッシュ最適化の例

  3. 今日のゴール • 高いCPUを買っても何もしなければアプリケー ションは速くならないという実感を持つ • キャッシュヒット率の重要性を理解する

  4. 大学院時代はスパコンで機械学習の訓練を高速化する研究をしていました • 機械学習の訓練データを共有の並列ファイルシステムに置いて計算ノードからアクセスするとlatencyが高い • 計算ノードのローカルストレージは低latencyだがコピーに時間がかるため少ない計算ノードだとペイしにくい https://dl.acm.org/doi/10.1145/3365109.3368768 というトレードオフの「いいとこどり」をする手法を提案し、Chainerで実装して訓練にかかる時間を評価

  5. 一方でスパコンといえば計算能力に関する研究が主流 • スパコン分野の研究でよく出てくるネタ ◦ 分散処理 ◦ GPU/FPGAを使った行列計算の高速化 ◦ 高速な連立一次方程式の解法 ◦

    高速な固有値問題の解法 こんな感じなので、研究室内の輪講でもこれらの話題につ いて学びました。 今日はその中でも面白かった「CPU性能の評価」に関する 話をご紹介します。
  6. CPUの理論性能と実効性能(1/2) • 理論性能 ◦ def; CPUのspecから求められる理論上出せる最高性能 ◦ 倍精度Flop/sで表記するのが一般的 ◦ 計算方法の一例

    ▪ clock * (FMA演算器の個数 x 2) * core数 * (最大SIMD幅 /64) ◦ Intel Xeon Gold 6126 (2.6GHz/12core) の例 ▪ 1 coreあたり: 2.6 GHz * (2 * 2) * (512/64) = 83.2 GFlop/s ▪ 1 socketあたり: 83.2 GFLOPS/core * 12 core = 998.4 GFlop/s (ガチ勢向け)AVX使用時はクロックがベースクロックよりも下がりますが本スライドでは同じと仮定します
  7. CPUの理論性能と実効性能(2/2) • 実効性能 ◦ def; 実際にapplicationを動かして計測された性能 ◦ こちらも倍精度Flop/sで表現するのが一般的 ◦ 計算方法の一例

    ▪ 2 GFlopsの計算を行うapplicationの実行に10秒 かかった • 2 GFlops / 10 sec = 0.2 GFlop/s
  8. 残念なお知らせ(1/2) • CPUの理論性能は基本的には出せない https://www.top500.org/lists/top500/2021/06/ 性能効率 (Rmax / Rpeak) [%] 82.2

    % 74.0 % 75.3 %
  9. 残念なお知らせ(2/2) • CPUの性能を阻害する多くのボトルネックが存 在する ◦ ネットワーク latency ◦ ストレージI/O latency

    ◦ メモリI/O latency ◦ 分岐予測ミス ◦ パイプラインストール etc.. <- 今日はここの話をします
  10. 計算回数とメモリI/O回数の比率を考える(1/2) • 計算するにはメモリからデータを読み書きしな ければならない double a = a + b;

    // 2回読み込み 1回書き 込み 上記のコードの場合、1回の加算に対して3回 (8 x 3 = 24 Byte) のメモリI/Oが発生している
  11. 計算回数とメモリI/O回数の比率を考える(2/2) • この時 ◦ メモリを24 Byte読み書きしないと1 Flop計算できな い • 言い換えると

    ◦ メモリを24 Byte読み書きするスピードの方が1 Flop計 算するよりも遅かったら、メモリI/Oがボトルネックに なる ◦ 逆に、メモリを24 Byte読み書きするスピードの方が1 Flop計算するよりも速かったら、CPUが1 Flop計算す
  12. わんこそばを食べる人とわんこそばを供給する人を考える (1/4) • わんこそば(以下WS)で例えてみる • WSを5杯/sec食べられる人が いるとする • この時WS消費速度のボトルネ ックになるのは

    ◦ WSを食べる人か? ◦ WSを供給する店員か? 5杯/secでWSを食べる人 n杯/secでWSを供給する 人
  13. わんこそばを食べる人とわんこそばを供給する人を考える (2/4) • 店員がボトルネックになるケース • 店員が3杯/secのスピードで供 給すると、3杯/secしか達成で きない • WSを食べる人は1秒で5杯食べ

    る能力があるのに、1秒あたり 2杯分無駄にしてしまう 5杯/secでWSを食べる人 3杯/secでWSを供給する 人 はよ持ってこんかい!
  14. わんこそばを食べる人とわんこそばを供給する人を考える (3/4) • WSを食べる人がボトルネックになるケース • 店員が10杯/secのスピードで 供給しても、5杯/secしか達成 できない • 店員は1秒あたりさらに5杯供

    給できるが持て余してしまう 5杯/secでWSを食べる人 10杯/secでWSを供給する 人 はよ食えや!
  15. わんこそばを食べる人とわんこそばを供給する人を考える (4/4) • WSの実効消費速度の推移をグラフにしてみる 0 1 5 WS消費速度 / WS供給速度

    (WS強度) 実効WS 消費性能 WS消費速度 > WS供給速度 WS消費速度 < WS供給速度 はよWS食えやゾ ーン はよWS持ってこい ゾーン 実効WS消費性能 = min(理論WS消費速度, 理論WS供給速度 * WS強 度) 1秒間に5杯持ってき て5杯食える Higher
  16. これはそのままCPUとメモリの関係になる • CPUとメモリの関係に置き換える 0 ? 理論性能 Flops per Byte (計算

    強度) 実効性能 [GFlops] CPU計算速度 > メモリI/Oバンド 幅 CPU計算速度 < メモリI/Oバンド幅 はよ計算しろやゾ ーン はよデータ持ってこい ゾーン 実効性能 = min(理論性能, 理論メモリI/O速度 * 計算強度) ここを知れば理論 性能を出すために 必要な計算強度が わかる Higher
  17. Intel Xeon Gold 6126の理論性能からバランスする計算強度を計算す る • CPU理論性能 ◦ 1 coreあたり:

    83.2 GFlop/s ◦ 1 socketあたり: 998.4 GFlop/s • メモリI/O理論バンド幅 ◦ 2666 MHz x 8 Byte x 6 Channel = 128 GB/s • CPU理論性能/メモリI/O理論バンド幅 ◦ 998.4 GFlop/s / 128 GB/s = 7.8 [Flop/Byte] ◦ ※一般的にはByte/Flopsで表現する ▪ B/F比率 = 1 / 7.8 = 0.128 [Byte/Flop]
  18. これはそのままCPUとメモリの関係になる • CPUとメモリの関係に置き換える 0 998.4 Flops per Byte (計算 強度)

    実効性能 [GFlops] はよ計算しろやゾ ーン はよデータ持ってこい ゾーン 実効性能 = min(理論性能, 理論メモリI/O速度 * 計算強度) 7.8 「計算強度7.8の applicationを動 かせば理論性能が 出せる」とわかっ た Higher CPU計算速度 > メモリI/Oバンド 幅 CPU計算速度 < メモリI/Oバンド幅
  19. ちょっと待て、計算強度7.8だと? • 計算強度7.8のコードを書くのはめちゃくちゃ大変 double a = a + b; //

    2回読み込み 1回書き込み • このコードだと計算強度は1 Flop / (8 * 3) Byte = 0.04167 • 理論性能を出すために必要な計算強度の5.3%でしかなく 全然性能を出せない。 • 計算強度7.8以上を達成するには↓みたいなコードじゃな いと無理(1回ロードしたbはレジスタに格納される想定) double a = b * … * b; // (合計125回bをかけ る)
  20. どうしてこうなった? • 現代はCPUに比べてメモリが相対的に遅い時代 https://www.extremetech.com/extreme/188776-how-l1-and-l2-cpu-caches-work-and-why- theyre-an-essential-part-of-modern-chips

  21. じゃあどうする? • 色々あります解決策 ◦ 1 cycleあたりの計算量を増やしてスループットを上 げる ▪ 並列化してマルチコアを活用する ▪

    SIMD命令を活用する ◦ メモリボトルネックを真っ当に解消する ▪ CPUキャッシュを使ってバンド幅を向上させる ▪ いいメモリを使ってバンド幅を向上させる
  22. CPUキャッシュはメモリの10倍から100倍高速 • 例えばスパコン富岳は高バンド幅なメモリとcacheを兼ね備えている https://www.hpci- Intel Xeon Gold 6126のBF ratioは 0.128なので富岳のメモリ方がBF

    ratio が高い
  23. 簡単な実験: キャッシュヒット率を上げるとどのぐらい早くなるか(1/2) • 正方行列 * 正方行列をnaiveに実装してみる for (i = 0;

    i < 1024; ++i) for (j = 0; j < 1024; ++j) for (k = 0; k < 1024; ++k) M3[i][j] += M1[i][k] * M2[k][j]; elapsed time = 6.079248 sec, 0.353248 GFLOPS https://github.com/serihiro/optimization_experiments コンパイルオプション: -O0 -std=c11 -Wall -Wextra
  24. 簡単な実験: キャッシュヒット率を上げるとどのぐらい早くなるか(2/2) • 正方行列 * 正方行列をキャッシュヒット率を 高めるように実装してみる for (i =

    0; i < 1024; ++i) for (k = 0; k < 1024; ++k) for (j = 0; j < 1024; ++j) M3[i][j] += M1[i][k] * M2[k elapsed time = 2.274633 sec, 0.944101 GFLOPS https://github.com/serihiro/optimization_experiments naiveに実装した時の3倍になった! for (i = 0; i < 1024; ++i) for (j = 0; j < 1024; ++j) for (k = 0; k < 1024; ++k) M3[i][j] += M1[i][k] * M2[k][j]; elapsed time = 6.079248 sec, 0.353248 GFLOPS コンパイルオプション: -O0 -std=c11 -Wall -Wextra
  25. 簡単な実験: (参考)手元の環境で一番はやくなったケース • 正方行列 * 正方行列をblock化してキャッシュヒッ ト率を高めつつAVX2命令(256bit)を使用する block_size = 16;

    for (i = 0; i < 1024; i += block_size) { for (j = 0; j < 1024; j += block_size) { for (k = 0; k < 1024; k += block_size) { for (ii = i; ii < i + block_size; ++ii) { for (jj = j; jj < j + block_size; ++jj) { for (kk = k; kk < k + block_size; ++kk) { elapsed time = 0.172988 sec, 12.414061 GFLOPS naive実装の約35倍を達成した!(コンパイルオプションが違うので直接比較はできないけど) コンパイルオプション: -O3 -mavx2 -std=c11 -Wall -Wextra
  26. まとめ • 現代はメモリよりもCPUがはるかに高速な時代 • 高いCPUに買い換えるだけでは性能は出ない • CPUの性能を引き出すにはキャッシュヒット率 を高めるコードを書くなどの人手による工夫が 必要

  27. 併せて読みたい(CPU性能やコンピュータアーキテクチャに関する本) • Samuel Williams, Andrew Waterman, and David Patterson. 2009.

    Roofline: an insightful visual performance model for multicore architectures. Commun. ACM 52, 4 (April 2009), 65–76. DOI:https://doi.org/10.1145/1498765.1498785 • Software Engineering Advice from Building Large-Scale Distributed Systems http://static.googleusercontent.com/media/research.google.com/en/us/people/jeff/stanford-295-talk.pdf • コンピュータアーキテクチャ技術入門 https://gihyo.jp/book/2014/978-4-7741-6426-7 • パタヘネ5版 https://www.amazon.co.jp/dp/4822298426/ • スーパーコンピュータ (岩波講座 計算科学 別巻) https://www.amazon.co.jp/dp/4000113070/ • High Performance Computing: Modern Systems and Practices https://www.amazon.co.jp/dp/B077NZ4SW3/
  28. appendix 1 • 行列積の実験をしたCPUのspec ◦ machdep.cpu.brand_string: Intel(R) Core(TM) i7-9750H CPU

    @ 2.60GHz ◦ machdep.cpu.core_count: 6 ◦ machdep.cpu.cache.L2_associativity: 4 ◦ machdep.cpu.cache.linesize: 64 ◦ machdep.cpu.cache.size: 256