再現しないバグは直せない── AI時代のソフトウェア品質とDST【#も読】のトップ画像

再現しないバグは直せない── AI時代のソフトウェア品質とDST【#も読】

投稿日時:
maguroのアイコン

Deno Land Inc. / ソフトウェアエンジニア

maguro

Xアカウントリンク
「あの人も読んでる」略して「も読」。さまざまな寄稿者が最近気になった情報や話題をシェアする企画です。他のテックな人たちがどんな情報を追っているのか、ちょっと覗いてみませんか?

みなさんこんにちは。

「あの人も読んでる」、第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は遅いのか?

Are Mutexes Slow? - YouTube

まずは、僕が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のアーキテクチャレベルの知識が必要であるということで、非常におもしろい動画でした。

この記事のつづきを読もう
新規登録/ログインしたらできること
  • すべての記事を制限なく閲覧可能
  • 限定イベントに参加できます
  • GitHub連携でスキルを可視化
ログイン
アカウントをお持ちでない方はこちらから新規登録