11月29日、海外のテクノロジーメディアPhoronixが「New Linux Patches Enhance Single-Threaded Performance On Many-Core CPUs」と題した記事を公開した。この記事では、多数のCPUコアを持つシステムにおいて、シングルスレッド処理の性能を向上させる新しいLinuxカーネルパッチについて詳しく紹介されている。

以下に、その内容を紹介する。
多コア時代に浮かび上がる「シングルスレッド処理のボトルネック」
近年のサーバーやワークステーションでは、100コア級のCPUが一般的となった。一方、多くのアプリケーションでは依然としてシングルスレッド処理が存在し、そのパフォーマンスはカーネル内部の実装次第で大きく左右される。
今回SUSEのGabriel Krisman Bertazi氏が提案したRFCパッチシリーズは、この問題に焦点を当てるもので、Linuxカーネル内部の rss_stat 構造体 に起因するオーバーヘッドの削減を目的とする。
rss_stat とは何か——そしてなぜ per-CPU なのか
rss_stat は Resident Set Size(RSS)、すなわち プロセスが実際に利用している物理メモリ量 の統計を保持するカーネル内部構造体だ。
Linuxはこの rss_stat を per-CPU (CPUごとに1つ)カウンター として実装している。これは、以下の理由による。
● なぜ per-CPU 構造が必要なのか?
RSS のカウンターは「メモリの割り当て」「解放」など、プロセス実行中に非常に頻繁に更新される。
もしこれが単一のグローバルカウンターであれば、
- ロック競合
- キャッシュライン競合
- コア間キャッシュ同期(特にNUMA環境で高コスト)
が発生し、スケールしない。
そこで Linux は CPUごとに“局所的な”rss_stat を持たせ、更新時にロックやキャッシュ競合を避けるという設計を採用している。
● なぜ fork 時に「全CPU分の rss_stat を必ず確保」するのか?
per-CPU 構造は、「CPUの数だけデータ構造を持つ」という前提がある。
つまり、新しいタスクを fork する際には:
- 全コア分の rss_stat の枠をあらかじめ作る
- どのCPUで実行されても即座にカウンターを更新できる状態にしておく
必要がある。
これは タスクが今後どのCPUにスケジュールされるかわからない ためだ。
Linuxスケジューラは状況に応じてタスクを任意のCPUに移動させる可能性があり、
その度に必要な per-CPU データを “後から”作るわけにはいかない。
したがって、
fork 時点で「全CPU分」を割り当てておくのは正しい実装だが、
多コア化が進むとこのコストが無視できなくなる
という事情がある。
これが、今回の最適化パッチが必要とされる背景にある。
パッチの狙い:シングルスレッドタスクの特性に基づく最適化
Gabriel Krisman Bertazi氏は、Jan Kara氏との議論を踏まえ、以下の前提に着目した。
シングルスレッドのタスクは、複数CPUから rss_stat を更新するケースが極めて稀である。
ならば、fork のたびに 256CPU 分の per-CPU カウンターを確保するのは無駄であり、次のような簡略化が可能になる。
- 通常の rss_stat 更新は ローカルCPU用の単一カウンター で処理
- 他CPUからの更新が必要になった場合のみ atomic カウンター で処理
この方式なら、fork 時の pcpu メモリ割り当てを行わずに済み、初期化と破棄のコストが大幅に削減される。
性能向上の結果:6〜15% の高速化
記事では、以下のようなベンチマーク結果が示されている。
- 256コアシステムでの人工forkベンチ → 6〜15%高速化
(/bin/true を大量に fork する負荷) - kernbench → 約1.5% 高速化
高コア時代のシングルスレッド最適化としては効果が大きく、特に EPYC や Threadripper といった多コアCPUシステムでの恩恵が期待される。
RFC パッチシリーズ
詳細を確認したい開発者は、以下のRFCパッチを参照できる。
現時点ではRFC段階だが、メインラインに取り込まれれば多コアCPU環境のシングルスレッド性能向上が期待される。
詳細はNew Linux Patches Enhance Single-Threaded Performance On Many-Core CPUsを参照していただきたい。