# 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)