Metaが暴いた/proc/interruptsの隠れたボトルネック

Linuxの「当たり前」が、数千台規模では致命的なコストになっていた。Metaのエンジニアが投じた一石が、カーネルの古い慣習を書き換えようとしている。

Metaが暴いた/proc/interruptsの隠れたボトルネック

Linuxの「当たり前」が、数千台規模では致命的なコストになっていた。Metaのエンジニアが投じた一石が、カーネルの古い慣習を書き換えようとしている。


/proc/interruptsの「読み取りコスト」という盲点

Linuxサーバーを運用する人間なら、/proc/interruptsを一度は開いたことがあるだろう。各CPUコアごとの割り込み回数がテキストで並ぶ、地味だが欠かせない情報源だ。

ところがMetaのエンジニア、ドミトリー・イルヴォーキンが問題を可視化した。監視ツールが数秒おきにこのファイルを読み取る環境では、seq_printfが処理時間の約47%を占めていたのだ。1台なら気にならない。だが数千台のサーバーが、数百コアを搭載し、常時このファイルをポーリングしている環境では話が違う。

監視ツールは/proc/interruptsを定期的にスキャンし、時系列データとしてエクスポートする。大規模フリートでは数秒ごとに全マシンでこの処理が走る。

コア数が増えるほどコストは線形に膨らむ。割り込みカウンターはCPUごとに存在するため、コア数の増加がそのまま出力量の増加に直結する。現代のサーバーが128コア、256コアと積み上げていく流れの中で、この「読み取りコスト」は年々肥大化する構造的問題になっていた。

printf問題——汎用性の代償

原因ははっきりしている。seq_printfは汎用的なフォーマット関数であり、内部でvsnprintfを呼び出し、フォーマット文字列の解析、数値変換、メモリコピーと多段の処理を経る。割り込みカウンターの出力のように「固定幅の10進数を大量に並べる」だけの用途には、あまりに重装備だ。

seq_printfのオーバーヘッドの内訳:vsnprintfが89%、その中でformat_decodeが24%、number関数が19%を占めていた。数値出力に特化すれば、この処理の大半をスキップできる。

イルヴォーキンの最初のパッチは、このseq_printfseq_put_decimal_ull_width(固定幅の10進数を直接出力するヘルパー関数)に置き換えるという、実にシンプルなものだった。リッチなフォーマット処理を迂回し、数値とスペースだけを最短経路で書き出す。

結果は明白だった。/proc/interruptsの読み取りにかかる経過時間が約29%短縮された。地味なファイル読み取りの最適化で3割近い改善というのは、カーネル開発者の感覚では相当なインパクトだ。

指標 最適化前 最適化後 改善幅
経過時間 4.27ms 3.00ms 約29%短縮
task-clock 3.42ms 2.39ms 約30%短縮
命令数 893万 702万 約21%削減
分岐ミス 1.94% 1.62% 改善

cat /proc/interrupts 実行時のperf stat計測値。seq_printfからput_decimalへの置き換え前後比較(V4パッチ)。出典:LKML

Gleixnerが主導する15パッチの全体像

この最適化は、単発のパッチにとどまらない。Linuxカーネルの割り込みサブシステムのメンテナであるトーマス・グライクスナーが、イルヴォーキンのアイデアを起点に/proc/interrupts全体の出力パイプラインを見直すV4パッチシリーズ(全15パッチ)へと拡張している。2026年3月31日にカーネルメーリングリストに投稿されたこのシリーズは、x86アーキテクチャ固有の割り込み記述をジェネリックな記述に揃える作業や、ゼロカウントのフォーマット回避、割り込み統計の配列ベース格納への移行など、構造的な改善を含む。

単なる「関数の差し替え」ではなく、/proc/interruptsの出力基盤そのものを再設計する動きだ。副次的な効果として、x86の割り込みイベント記述がジェネリックなものと統一されるなど、コードの整理も進む。

Making sure you’re not a bot!

なぜテキストインターフェースが残り続けるのか

Phoronixのフォーラムでは、この記事に対して興味深い議論が起きている。「そもそもなぜ/procとsysfsにバイナリインターフェースを使わないのか」という根本的な問いだ。

技術的には正論だ。バイナリ形式ならカーネル側のフォーマットコストもユーザー空間でのパースコストも激減する。だがコミュニティの反応は冷静で、「UNIXの流儀はプレーンテキスト」「netlinkインターフェースを追加しても、ファイルシステムレイヤーのオーバーヘッドは残る」という意見が出ている。

あるフォーラムメンバーは、バイナリ/procインターフェースがフォーマットコストとパースコストの両方を削減できると認めつつ、「テキストインターフェースはしばらく使い続けられる。だからこそ、今の最適化にも意味がある」と指摘した。

正論と現実のあいだで、最も実用的な選択が取られた。テキストインターフェースを維持したまま、その内部実装を高速化する。Linuxカーネル後方互換性への徹底したこだわりが、こうした「地味だが確実な改善」を選ばせる。


スケールが変える「些細な問題」の重み

この最適化は、単体では「29%速くなりました」という地味な話だ。だが本質は、ハイパースケーラーの視点がカーネルの常識を更新するという構図にある。

Metaのフリートでは、割り込みの監視だけで無視できない計算資源が消費されていた。1台あたりのコストが微小でも、数万台に掛け算すればCPU時間の浪費は膨大になる。しかもコア数増加のトレンドは加速している。今日の「些細なオーバーヘッド」は、明日の「深刻なボトルネック」になりうる。

Linuxカーネルの強さは、こうしたフィードバックループにある。巨大な本番環境で発見された問題が、パッチとしてアップストリームに還元され、すべてのLinuxユーザーに恩恵が届く。Metaの数千台が踏んだ地雷を、次にサーバーを立てる誰かが踏まずに済む。

オープンソースの本質的な価値は、こういう地味な場所にこそ宿っている。


参照元

他参照

関連記事