- Cosmopolitan Libcは、複数のオペレーティングシステムで実行可能なバイナリを提供することで知られており、本番環境でも優れた性能を発揮できるCライブラリである。
- 性能を実証するためのミューテックスベンチマーク: 30個のスレッドが同じ整数を100,000回インクリメントするテストを通じて、ミューテックス実装の性能を比較している。
- Windows
- Cosmopolitan
pthread_mutex_t はMicrosoftのSRWLOCKより2.75倍高速で、CPUリソースの使用量は18分の1である。
- Cygwinのミューテックスは性能が非常に低く、スピンロックを使ったほうがよいほどである。
- Linux
- Cosmopolitan
pthread_mutex_t はglibcより3倍、musl libcより11倍高速である。
- CPU使用量はglibcより42分の1、musl libcより178分の1である。
- MacOS
- Apple LibcはCosmopolitanのミューテックスよりわずかに優れた性能を示す。
- CosmopolitanはUlrich Drepperの論文 "Futexes Are Tricky" に基づくアルゴリズムを使用して性能を最適化している。
どうしてそれが可能なのか?
- Googleの著名なエンジニアであるMike Burrowsが書いた nsyncライブラリ を使うことで、優れた性能を発揮している。
- 彼は、かつてGoogleの競合だったAltavistaをコーディングした人物でもある。
- nsyncのトリックと分析
- nsyncは、競合がないときに高速にロックできるよう、楽観的なCAS(compare and swap)を即座に使用する。
- ロックを取得できない場合、nsyncは呼び出しスレッドを待機者の双方向リンクリストに追加する。
- 各待機者には、独立したキャッシュライン上に専用のセマフォが割り当てられる。
- スレッドが待機状態に入ると、もはや基本ロックには触れない。
- これが重要な理由は、Ulrich Drepperの文書 "What Every Programmer Should Know About Memory" で確認できる。
- 複数のコアが同じキャッシュラインに触れると、プロセッサ内で大きな通信オーバーヘッドが発生する。
- nsyncはfutexを使ってオペレーティングシステムの助けを借りる。
- futexはLinuxで数年前に発明された優れた抽象化で、他のOSでもすぐに高速に使われるようになった。
- MacOSではulock、Windowsでは
WaitOnAddress() と呼ばれる。
- CosmoがサポートするOSのうち、futexがない唯一のOSはNetBSDである(POSIXセマフォをカーネル空間で実装しており、各セマフォごとに新しいファイルディスクリプタを作成する必要がある)。
- futexとセマフォの重要な点は、OSがスレッドをスリープさせられることにある。これによりnsyncは、実行すべき作業がないときにCPU時間を消費せずに済む。
- nsyncは「長い待機(long wait)」の概念によって飢餓状態を回避する。
- 待機者が30回起こされ、内部的にロック取得に失敗すると、まだ待っていないスレッドが取得するのを防ぐビットをロックに追加する。
- キューがある程度解消されるまで、他のすべてのスレッドに対して最初のCASは失敗する。
- nsyncは「指定された起床役(designated waker)」の概念を使い、ベンチマークされたユースケース(小さなクリティカルセクションを持つ競合ロック)を高速化する。
- ロックの取得を試みるスレッドが起きているとき、基本ロックにこのビットが設定される。
- nsyncでは、アンロック関数がロックを待っている次のスレッドを起こす役割を担う。
- このビットがあることで、アンロックするスレッドは、1つのロッカーがすでに起きているため2つ目を起こす必要がないことを理解できる。
オンラインでの実証
- Cosmopolitanミューテックスを使ったソフトウェアのライブデモを通じて性能を確認できる。
- http://ipv4.games/ ウェブサーバーは、大規模なDDOS攻撃にも耐えられる性能を示している。
1件のコメント
Hacker Newsの意見
新しいミューテックス実装とその性能比較を見るのはいつも興味深い。ただし今回のベンチマークはマイクロベンチマークのように見える。大規模なマルチスレッドプログラムを使って性能をテストするのが一般的だ。複雑なワークロードでは、ミューテックスの性能は異なって見える
Cosmopolitan Mutexesが優れている理由は、nsyncというライブラリを使っているからだ。このライブラリはGoogleの著名なエンジニアであるMike Burrowsが書いた。ただ、このミューテックス実装がベンチマークに含まれていない理由が気になる
wait()、notify_one()関数でもっと簡単に実装できるCosmo/ape/redbeanについて好意的な意見は多いが、実際に使っている人を見たことがない。これらのツールは本当に革新的なのに、まだ広く使われていないのだろうかと気になる
Cosmopolitanプロジェクトは高く評価しているが、誇張された優位性の主張には疑いを感じる。すべてのCライブラリが同じトリックを採用していないのは、特定のアーキテクチャやCPUモデル、ワークロードでしか常に速くないからかもしれない
本番環境では、速度や効率性より信頼性のほうが重要だ。システムを壊さないことのほうが大切だ
nsyncのミューテックス解放関数で見つけたバグを修正したことがある。Cosmopolitanプロジェクト内でnsyncの改善点を見ている。upstreamのnsyncを使うのが安全なのか気になる
スレッドとミューテックスは、コンピュータサイエンスで最も複雑な要素の1つだ。新しい実装が大規模に使われるまでは常に懐疑的だ。Javaが登場したとき、Solarisでは多くのスレッドとミューテックスのバグが明らかになった
nsyncがSRWLOCKよりはるかに速い点には驚く。win32 SRWLOCKsをリバースエンジニアリングした経験がある
ミューテックスを見るたびに否定的な感情が湧く。多くのコードでロックを取り除き、キューやメッセージング抽象化に置き換える作業をしてきた。最近はさまざまなロックアルゴリズムを探求している。nsyncのような効率的なロックツールを使ってみたい