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

SIMD化とは何か / Basics of SIMD

SIMD化とは何か / Basics of SIMD

SIMD化の簡単な説明

Avatar for kaityo256

kaityo256

April 28, 2020
Tweet

More Decks by kaityo256

Other Decks in Education

Transcript

  1. 14 ※Very Long Instruction Word ソフトウェアにがんばらせる コンパイラがデータと 命令を並べておく それをノーチェックで 演算機に流しこむ

    依存関係チェックが不要→ハードウェアが簡単に 神のように賢いコンパイラが必要 後方互換性を失う 組み込み向けでは人気も HPC向けとしてはほぼ絶滅
  2. 19 1 3 4 8 2つのレジスタに4つずつ値を載せる(256ビットの場合) 3 8 2 5

    「同じ位置」同士で同時に独立な演算をする 1 3 4 8 3 8 2 5 4 11 6 13 +
  3. 20 3 8 2 5 1 3 4 8 4

    11 6 13 + 3 1 4 + 一つの計算をするのと同じ時間で 複数の計算を同時に実行できる CPUの理論ピーク性能は「SIMD幅を使い切った時」の値 SIMDが使えていなければ、数分の一の性能しか出せない
  4. 21 各位置ごとに異なる演算はできない 1 3 4 8 3 8 2 5

    4 11 6 13 + 複数のデータ(Multiple Data)に 単一の演算 (Single Instruction)を実行するから SIMD (Single Instruction Multiple Data)
  5. 25 const int N = 10000; double a[N], b[N]; void

    func(void){ for(int i=0;i<N;i++){ a[i] += b[i]; } } 最近のコンパイラは簡単なコードなら勝手にSIMD化してくれる test.cpp たとえばこんなファイルを用意する
  6. 26 Intelコンパイラに食わせて、最適化レポートを出力 icpc -O3 -qopt-report=2 -c test.cpp test.optrpt LOOP BEGIN

    at test.cpp(5,3) remark #15300: LOOP WAS VECTORIZED LOOP END const int N = 10000; double a[N], b[N]; void func(void){ for(int i=0;i<N;i++){ a[i] += b[i]; } } test.cpp test.cppの5行目のループを ベクトル化したよ
  7. 28 自分でSIMD命令を書くことでSIMD化する v4df vdq_1_b = (vqj_1 - vqi); v4df vdq_2_b

    = (vqj_2 - vqi); v4df vdq_3_b = (vqj_3 - vqi); v4df vdq_4_b = (vqj_4 - vqi); tmp0 = _mm256_unpacklo_pd(vdq_1_b, vdq_2_b); tmp1 = _mm256_unpackhi_pd(vdq_1_b, vdq_2_b); tmp2 = _mm256_unpacklo_pd(vdq_3_b, vdq_4_b); tmp3 = _mm256_unpackhi_pd(vdq_3_b, vdq_4_b); vdx = _mm256_permute2f128_pd(tmp0, tmp2, 0x20); vdy = _mm256_permute2f128_pd(tmp1, tmp3, 0x20); vdz = _mm256_permute2f128_pd(tmp0, tmp2, 0x31); 実際にはアセンブリに対応したC言語の関数を呼ぶ SIMD命令はアセンブリなのでアセンブリで コードを書くことになる
  8. 30 場合によって最適なデータレイアウトが異なる 例:三次元の座標データを持つ原子のまとまりを表現したい X Y Z X Y Z X

    X X X Y Y Y Y Z Z Z Z 方法2: 同じ成分をまとめる Structure of Array (SoA) 方法1: 順番に並べていく Array of Structure (AoS) SoAとAoSの変換は、コードをほぼ全て書き直しに・・・ どちらが良いか、CPUやプログラムごとに違う