# Everyone Should Know SIMD [[Mitchell Hashimoto]] のブログ記事。SIMD (Single Instruction, Multiple Data) を「特殊な最適化技法」としてではなく、一定の規則的な「型」を持つ、日常的に使えるパターンとして紹介する。ターミナルエミュレータ [[Ghostty]] の実装(言語は [[Zig]])から実例を引く。 ## SIMD とは何か SIMD は CPU が複数の値を並列に演算する仕組みだ。1 バイトずつ比較する代わりに、1 命令で 4 バイト・8 バイト、あるいはそれ以上をまとめて比較できる。`for (byte in bytes)` のようなループは SIMD 化の好機であり、「データを 4 倍・8 倍、あるいはそれ以上速く処理する」変換になりうる。 前提条件は「十分な量のバイト列を処理すること」。simdutf や simdjson のようなプロジェクトは高度な SIMD 技法を示すが、日常的な SIMD 利用はもっと単純なパターンに従う。 ## SIMD コードの共通形(5 段階) 記事の核となる主張は、SIMD コードが次の 5 段階の一貫した構造に従うという点だ。 1. 定数をブロードキャストし、ベクトルアキュムレータを初期化する 2. 入力をベクトル幅ぶんずつループする 3. 全レーンにまたがって比較・演算を並列実行する 4. ベクトル結果をリダクション(縮約)するか格納する 5. 端数(ベクトル幅に満たない残り)をスカラーループで処理する ## Ghostty の実例 対象は「コードポイントが `0xF` を超える値を探索する」処理。 スカラー実装: ``` while (end < cps.len and cps[end] > 0xF) end += 1; ``` SIMD 実装(Zig、`@Vector` 組み込み型を使用): ``` if (simd.lanes(u32)) |lanes| { const V = @Vector(lanes, u32); const threshold: V = @splat(0xF); while (end + lanes <= cps.len) : (end += lanes) { const values: V = cps[end..][0..lanes].*; const greater_than_threshold = values > threshold; if (@reduce(.And, greater_than_threshold)) continue; const mask: std.meta.Int(.unsigned, lanes) = @bitCast(greater_than_threshold); end += @ctz(~mask); break; } } while (end < cps.len and cps[end] > 0xF) end += 1; ``` この実装は ARM NEON で最大 4 倍、AVX2 で最大 8 倍、AVX-512 で最大 16 倍のスループット改善が見込め、AVX2 上の実測では約 5 倍の高速化を確認したという。末尾の `while` ループが、ベクトル幅に満たない残り要素を処理する第 5 段階(スカラー端数処理)にあたる。 ### 各段階の対応 - **段階 1(定数ブロードキャスト)**: 冒頭 3 行がベクトル型を定め、比較値を全レーンへ複製する。`@splat(0xF)` が閾値を複製したベクトルを作る。 - **段階 2(ベクトル幅ループ)**: レーン数ぶん進みながら完全なベクトル幅チャンクを処理する。端数は別処理に回す。 - **段階 3(SIMD 演算)**: `values > threshold` が全レーンで同時に実行される。「これは 1 個のベクトル CPU 命令にマップされる」。 - **段階 4(リダクション)**: `@reduce(.And, greater_than_threshold)` で全レーンが条件を満たすか判定する。特定の失敗レーンを探す場合は `@bitCast` でブール値ベクトルを整数に変換し、`@ctz`(先頭ゼロ数カウント)で最初の失敗位置を特定する。 - **段階 5(スカラー端数)**: 元のスカlaarループがベクトル幅に満たない残りを処理し、SIMD 非対応 CPU 向けのフォールバックも兼ねる。 ## なぜコンパイラに任せられないのか コンパイラは単純なループを自動ベクトル化できるが、「一般に非常に不得手」だとハシモトは述べる。パフォーマンスが重要なコードでは「ベクトル化は明示的かつ予測可能であってほしい」として、手動 SIMD を選好する立場を示す。この主張は、既存の [[SIMDベクトル処理]] ページにある「自動ベクトル化は難しい」という知見(`__restrict__` 修飾の要否など)と一致する。 ## 結論 大きな連続データを処理するループにこの 5 段階のパターンを認識できれば、SIMD は特殊技能ではなく日常的に使える道具になる、というのが記事の主旨。 ## 出典 - Mitchell Hashimoto, "Everyone Should Know SIMD", https://mitchellh.com/writing/everyone-should-know-simd (取得日: 2026-07-27)