みなさんこんにちは。
「あの人も読んでる」、第17回目の投稿です。maguro (X @yusuktan)がお届けします。
前回の記事でJetBrains TVのチャンネルを紹介した際、Rust界隈で著名なJon Gjengsetさんのインタビュー動画を取り上げました。その動画をきっかけにしてか、優秀なYouTubeのレコメンドアルゴリズムが、あるチャンネルをレコメンドしてくれました。それがJane StreetのYouTubeチャンネルです。
Jane Streetは、世界有数のトレーディング企業で、関数型プログラミング言語OCamlを全面的に採用していることでも知られています。そのJane Streetが運営するYouTubeチャンネルでは、ソフトウェアエンジニアリングに関する非常に質の高いトーク動画が多数公開されています。
今回は、このJane Streetチャンネルで公開された動画を2つご紹介します。また、そのうちの1つの動画と関連するテーマとして、僕が最近強く惹かれている「決定論的シミュレーションテスト(Deterministic Simulation Testing, DST)」に着目して、金融に特化したデータベースであるTigerBeetleについての記事も1つご紹介していきます。
Mutexは遅いのか?
まずは、僕がJane Streetチャンネルを発見するきっかけとなった動画から。前回の記事でも紹介したJon Gjengsetさんが、"Are Mutexes Slow?" というテーマで講演しています。
「Mutexは遅い。読み取りが多い処理ならReader-Writer Lock(RWLock)を使うべきだ」―― これは並行プログラミングでよく耳にするアドバイスです。しかし、Gjengsetさんが実際にベンチマークを取ると、予想に反する結果が現れます。
読み取り専用の処理であるにもかかわらず、スレッド数を増やすとRWLockはMutexよりも遅くなるのです。
真のボトルネック:MESIプロトコル
この現象の原因は、ロックの仕組みそのものではなく、CPUキャッシュのコヒーレンス(一貫性維持)にある、とGjengsetさんは説明します。
現代のCPUでは、各コアがL1、L2、L3キャッシュを通じてデータに高速アクセスしています。複数のコアが同じメモリ領域(キャッシュライン:64バイト単位)を扱う際には、MESIプロトコル(Modified, Exclusive, Shared, Invalid)というルールに基づいてデータの一貫性が保たれます[1]。
ここで重要なのは、共有データに書き込みを行うには、他のすべてのコアのキャッシュを無効化(Invalid)して自分だけが独占(Exclusive)する状態を作る必要があるということです。このコア間通信のコストは、L1キャッシュへのアクセスに比べて約30倍も遅い。これこそがパフォーマンス低下の根本原因です。
RWLockで「読み取りロック」を取得する処理は、内部的には「現在のReader数を記録するカウンターへの書き込み(インクリメント)」です。つまり、100個のスレッドが読み取りロックを取ろうとすると、100個のコアがすべて順番にキャッシュラインを独占してカウンターを書き換える「キャッシュラインのピンポン」が発生してしまいます。
Left-Right データ構造
Gjengsetさんは、この問題に対する解決策として自身が研究した「Left-Right」データ構造を紹介しています。
仕組みはシンプルで、データのコピーを2つ(LeftとRight)持ちます。読み取り側はアトミックなポインタが指す一方のコピーを読み、書き込み側はもう一方を更新してからポインタを切り替えます。各Readerスレッドには専用のカウンター(別々のキャッシュライン上)が与えられるため、Reader同士がキャッシュラインを取り合う必要がなくなり、スレッド数に比例してパフォーマンスが向上します。
ただし、メモリ消費が2倍になること、複数の書き込みに対応していないこと、結果整合性であることなど、トレードオフは存在します。Gjengsetさんは結論として、「真のコストはロックそのものではなく、データ共有に伴う"調整(Coordination)"にある」と述べています。
MutexとRWLockは、一見するとそれぞれを使うべきユースケースが明確なように思えますが、ベンチマークを取ってみると直感と反する結果になりうるということ。また、その挙動を理解するために、CPUのアーキテクチャレベルの知識が必要であるということで、非常におもしろい動画でした。
個人的な話をすると、昨年末まで通っていた大学院で High Performance Computer Architecture という授業を受けたのですが、そこで学んだCPUのキャッシュコヒーレンスの復習になりました。また、普段から馴染みのあるMutexやRWLockのパフォーマンス特性も、キャッシュコヒーレンスに関わっているんだという気づきが得られました。
Antithesis ―― 決定論的シミュレーションテストの革命児
Why Testing Is Hard and How to Fix It with Will Wilson - YouTube
続いて紹介するのは、同じくJane Streetチャンネルで公開された、Antithesis社の共同創業者兼CEOであるWill Wilsonさんへのインタビュー動画です。
Antithesisは、ソフトウェアの決定論的シミュレーションテスト(Deterministic Simulation Testing, DST) を実現するプラットフォームを提供する企業です。
また自分語りになってしまうのですが、大学院で受けたDistributed Computingの授業で、プログラミング課題としてDSLabsというものが使われていました。分散合意プロトコルの1つ Paxos を実装するプロジェクトですが、そこでテストの仕組みとして使われていたのが、まさにこのDSTと似たようなものでした。分散システム内の各ノードを純粋な状態マシンとして実装し、テストフレームワーク側がネットワーク通信やタイマーを完全に制御することで、メッセージの遅延や欠落、入れ替わりなどといったあらゆる可能性をもつ状態空間を網羅的に探索するのです。課題を通してこの仕組みに出会って以来、DSTに魅了され、いろいろと情報を集めるようになりました。
閑話休題。以下、インタビュー動画で話されている内容をご紹介します。
なぜ「決定論」が重要なのか
ソフトウェアのバグを見つける手法として、ランダムな入力を用いる「ファジング」や「プロパティベーステスト」は強力です。しかし、分散システムのようにスレッドの実行順序やネットワーク遅延などの非決定性が強く入り込むソフトウェアでは、それらを十分に活用するのが非常に困難でした。
その最大の原因は、コンピュータの非決定性です。スレッドの実行順序、タイマー、ネットワークの遅延、OSのスケジューリングなど、同じプログラムに同じ入力を与えても毎回異なる動作をしてしまいます。「テストでバグを見つけても二度と再現できない」というのは、分散システムの開発者なら誰もが経験したことのある悪夢でしょう。バグを見つけたは良いものの、原因を探るにはログなどの情報が足りず、ログを足して再度テストを実行してみると、同じバグを発生させられない……僕自身、これまでのキャリアの中で思い当たる節がたくさんあります。
ハイパーバイザによる完全な決定論
Antithesisは、この問題を根本から解決するアプローチを取りました。OSや言語ランタイムに依存するのではなく、独自のハイパーバイザ(仮想マシンの監視プログラム) を構築することで、完全に決定論的なシミュレーション環境を作り上げたのです。
これにより、ユーザーはアプリケーション本体のコードを大きく書き換えることなく [2]、高度なバグ探索と「100%再現可能なバグ報告」の恩恵を受けられます。Wilsonさんは、完璧な仕様を用意しなくても、DatadogやCloudWatchのようなモニタリングツールで設定するアラート条件(「メモリがXを超えないこと」「特定のエラーログが出ないこと」など)をテストのプロパティとして活用するだけでも絶大な効果があると語っています。
AI時代におけるDSTの重要性
個人的に最も印象的だったのは、AI時代におけるDSTの意義についての議論です。
AIコーディングエージェントの登場により、コードを書く速度は飛躍的に向上しました。しかし、生成された大量のコードが「正しく動くか検証するプロセス」が新たなボトルネックになっています。Wilsonさんは、AIがテストを通すために強引な修正を行い、システムのアーキテクチャや保守性を破壊してしまう「Evil Genie(邪悪な精霊)」現象について警鐘を鳴らしています。
僕がDSTに強く惹かれる理由もまさにここにあります。AIエージェントに十分なコンテキストと即座のフィードバックを与えれば、多くのバグを自律的に修正できる時代になりつつあります。しかし、その前提として「バグが本当に修正されたかどうか」を確実に検証できる仕組みが不可欠です。非決定的な環境では、AIが「修正した」と判断しても、実際にはたまたまテストが通っただけかもしれません。決定性こそが、AIによるバグ修正の信頼性を担保する鍵と考えています。
TigerBeetle ―― DSTを実践するデータベース
AntithesisのDSTに感銘を受けた流れで、DSTを積極的に活用しているプロダクトを紹介します。TigerBeetleです。
TigerBeetleは、金融トランザクション処理に特化したデータベースです。SQLの汎用的なインターフェースではなく、借方(debit)と貸方(credit)をファーストクラスのプリミティブとして扱う、極めて特化した設計になっています。
徹底した設計哲学
TigerBeetleの技術的な特徴は多岐にわたりますが、特に注目すべき点をいくつか挙げます。
- Zigによる実装: TigerBeetleはZigで書かれています。静的メモリアロケーションが可能で、Cエコシステムへのアクセスも容易なZigは、予測可能性と制御性を重視するTigerBeetleの哲学と合致しています。
- 外部依存ゼロ: 外部ライブラリに一切依存せず、すべてを自前で実装しています。ファイルシステムの抽象化すらバイパスし、
O_DIRECTで直接ディスクに書き込む徹底ぶりです。 - TigerStyle: NASAの Power of Ten ルールに基づいたコーディング規約「TigerStyle」を採用しています。関数あたり最低2つのアサーションを必須とするなど、堅牢性を設計段階から組み込んでいます。
VOPR ―― DSTの実践
そして、TigerBeetleがDSTを実践するために構築したのがVOPR(Viewstamped Operation Replicator) と呼ばれるテストシステムです。
Amplify Partnersの記事によれば、VOPRは1000個のCPUコア上で継続的に実行され、1日あたり約2000年分に相当する分散システムのランタイムをシミュレーションしています。ネットワーク障害、ディスク障害、クロックのずれなど、あらゆる障害シナリオを決定論的に再現し、バグを見つけた場合は100%再現可能な形でレポートされます。
ここにDSTの別の利点が現れています。つまり、実際の時間経過を待たずに即座に次のタイマーイベントを発火させる、ということが可能であるということです。例えば、「1秒後に処理Xを行う」というイベントがスケジューリングされている場合、実際に現実世界での1秒を待つことなく、シミュレータ上の時刻を1秒進めて処理Xを行うことで、時間を圧縮することができます。
この徹底したDSTへの投資もあって、プロダクション品質のコンセンサスエンジンとストレージエンジンを3.5年で作り上げることに成功しています。
おわりに
今回は、Jane StreetのYouTubeチャンネルとの出会いをきっかけに、CPUキャッシュの奥深さからDSTの革新性まで、幅広い話題を取り上げました。
3つのコンテンツに共通しているのは、「ソフトウェアの振る舞いを深いレベルで理解し、制御する」という姿勢です。Gjengsetさんのトークではハードウェアレベルのキャッシュの振る舞いを理解することの重要性が語られ、AntithesisとTigerBeetleではシステム全体を決定論的に再現することで信頼性を担保するアプローチが示されました。
特にDSTは、AI時代のソフトウェア開発において鍵となる技術だと僕は考えています。AIが書いたコードの正しさを保証するためには、テストの再現性と決定論が不可欠です。今後もこの領域の動向を追っていきたいと思います。
また次回、おすすめコンテンツを紹介していきます。お楽しみに!
maguroさんの「も読」過去記事
- ライブコーディング視聴のすすめ in 2026(3月6日公開)
- OSSメンテナの憂鬱 ―― "AI Slop" がもたらす疲弊(2月6日公開)
- なぜApache IggyはTokioを捨てたのか、なぜMicrosoftはRustに賭けるのか(1月12日公開)

