世界を動かす技術を、日本語で。

現代プロセッサアーキテクチャのためのアルゴリズム

2025年7月23日原文(lemire.github.io)

概要

  • Daniel Lemire教授による 現代プロセッサ の性能と最適化手法の解説
  • 命令数削減並列処理 による高速化技術の紹介
  • SIMDSWAR などのデータ並列性活用事例
  • 分岐予測パイプライン の効率化ポイント
  • 実測値や ベンチマーク の注意点と結論

現代プロセッサの進化と性能指標

  • Xeon Max プロセッサは 64 GB HBM を搭載し、 800 GB/s の帯域幅を実現

  • プロセッサの クロック周波数 は4 GHz以上、1サイクルは0.25ナノ秒

  • 1バイト/サイクル で4 GB/sの処理速度

  • CPUボトルネック 発生の容易性

  • トランジスタ数の増加 とその用途(コア数増加、スーパースカラ実行、投機的実行、キャッシュ拡大、SIMD強化)

    • 例: Apple M4は 4.5 GHz/28億トランジスタ、AMD Zen 5は 5.7 GHz/500億トランジスタ

命令数削減とバッチ処理

  • 命令数最小化 がバッチ処理での最適性能に直結
  • バッチ処理単位の拡大 による命令節約
  • 分岐・メモリアクセス・I/O が性能制約要因

数値パースの最適化

  • fast_float::from_chars による高速数値パース
  • 主要ブラウザやGCC, C#, Rust で採用
  • 従来手法(strtod等)より大幅に命令数削減
  • SWAR (SIMD within a register)による並列化
    • 64bitレジスタを8バイトとして扱い、ASCII判定を効率化

バッチ処理とループアンローリング

  • forループのアンローリング で1回の繰り返しあたりの命令数削減
  • 例: 乗算処理で 6-7命令→3-5命令 へ短縮

ランダムシャッフルの高速化

  • Knuthのアルゴリズム をバッチ化し、乱数生成・分岐数を削減
  • Apple M4 で大規模配列(8MB)に対して高速化実績

分岐予測とUnicode検証

  • UTF-16検証 で分岐が多いと性能低下
  • 有限状態機械(FSM) を活用し、分岐レスで高速検証
  • Apple M4 で1文字/サイクルの検証速度(4GB/s)
  • 分岐の学習限界 :Apple M4で1万ランダム分岐まで対応可能

パイプラインとメモリレベル並列性

  • パイプライン によるレイテンシ隠蔽
  • メモリレベル並列性 :大規模配列やSattoloのアルゴリズムでランダムアクセスパス生成
  • Littleの法則 :レイテンシはスループットに悪影響、並列性で解消

Bloomフィルタとデータレベル並列性

  • Bloomフィルタ :キャッシュミス半減、8ハッシュ関数利用
  • SIMD (Single Instruction, Multiple Data):1命令で16バイト以上を同時処理
    • ASCII小文字化デルタ計算 などで実用
    • Apple M4 はSIMD自動ベクトル化対応

UTF-16のSIMD補正関数

  • v8(Google Chrome, Microsoft Edge) で実際に導入

  • SIMD補正関数 は非SIMD検証より高速

    • AVX2/AVX-512/NEON/SVE/SVE2/RISC-V vector など各アーキテクチャでSIMDサポート

関連プロジェクト

  • simdjson :世界最速のJSONパーサー https://simdjson.org
  • simdutf :Unicode処理&Base64 https://github.com/simdutf/simdutf

ベンチマークと実測値の注意点

  • 測定値は正規分布とは限らない
  • 現実の測定値 :最小値が信頼できる指標となる場合が多い
  • 平均値と最小値の差(マージン) を重視

結論とルール

  • プロセッサは進化し続け、幅広い並列処理が可能
  • ホットスポット最適化よりも全体の命令数削減が重要
  • 分岐が多いコードは合成ベンチマークで良く見えるが、実際には注意が必要

参考:プロセッサの分岐学習能力(Apple M4)

| size | ns/value | GHz | cycles/value | instr/value | i/c | |--------|---------:|-----:|-------------:|------------:|-----:| | 1048576| 1.59 | 4.51 | 7.20 | 8.01 | 1.11 | | 524288 | 1.50 | 4.51 | 6.76 | 8.01 | 1.19 | | 262144 | 1.31 | 4.51 | 5.90 | 8.01 | 1.36 | | 131072 | 0.76 | 4.52 | 3.43 | 8.01 | 2.34 | | 65536 | 0.49 | 4.52 | 2.20 | 8.01 | 3.64 | | 32768 | 0.49 | 4.52 | 2.19 | 8.02 | 3.66 |

Hackerたちの意見

今日、SEA 2025でこれが配信されたみたいだね。早く動画が見られるといいな! https://x.com/lemire/status/1947615932702200138

残念ながら、講演は録音されてないと思うよ。

失礼なこと言いたくないけど、LLVMが同じ組織の手にあるってのは、プラットフォームへのアクセスをコントロールしているのが狂ってる理由そのものだよね。編集 - #64 E!それに、いつも言ってるけど、人間の体は人間が持ってる中で一番エラーが出やすい測定器だよ。

ちょっと物議を醸すかもしれないけど、Red Hatがx86_64_v1とx86_64v2を非推奨にした時、みんな泣いてたよね…。

もう少し具体的に教えてくれない?特定のプラットフォームに最適化しすぎて、他のコンパイラやアーキテクチャに一般化できないから?具体的に何が不満なの?

LLVMは具体的に誰の手にあるの?

LLVMとGCCはプロセッサーメーカーから直接サポートされてるよ。アップルとインテルはそれぞれ独自のLLVMバージョンを持ってるけど、GCCとの互換性を壊さず、明示的にポーティングを妨げなければ問題ないと思う。個人的にはGCCスイートしか使ってないけど、LLVMはあまり好きなコンパイラじゃないな。GCCチームが頑張るきっかけを与えてくれたことには感謝してるよ。

AppleはまだUTF-16を使ってるの?

これってアップルの話?それはさておき、まだ多くのプログラミング言語のランタイムがUTF-16を使ってるよ(例えば、Java、Qt、Haskellとか)。Windowsも確実にUTF-16を使ってるしね。

JavaScriptはそうだから、ウェブもそうだし、だからアップルもUTF-16に気を使ってるんじゃないかな。

NSStringは内部的にはUTF-16だよね。https://developer.apple.com/documentation/foundation/nsstrin... でも、NSStringにUTF-8の文字列を入れたり出したりするのは簡単だから、内部の表現はあんまり重要じゃないんだ。もっと重要なのは、macOSのユーザー向けの部分は全部UTF-8だってこと。例えば、UTF-8でエンコードされたUNICODE文字列リテラルをCのソースファイルにそのままコピー&ペーストして、printf()すれば、テキストエディタやロケール設定をいじらなくてもターミナルに正しく表示されるよ。

Pentium 4は3.8GHzには達してなかったよ。1.4GHzくらいで溶けちゃった。

Hacker Newsで議論の続きを見る