15年前のPCがゲームで蘇る、Linuxスケジューラ再設計

15年前のPCがゲームで蘇る、Linuxスケジューラ再設計

Linuxスケジューラの長年の歪みに、Intelの開発者ペーター・ゼイルストラがメスを入れた。15年前のSandy Bridgeに2017年のRX 580という「ポテト」マシンで、ゲーム中のFPS最小値が5倍以上に跳ね上がっている。


開発者本人が「最悪」と呼ぶ仕組みに、本人が手を入れる

Linuxカーネルのcgroupスケジューラに、根本的な手術が始まっている。手を入れているのは、長年スケジューラのメンテナを務めるIntel所属のペーター・ゼイルストラ(Peter Zijlstra)本人だ。

ゼイルストラはパッチシリーズの冒頭で、cgroupスケジューリングを「a pain in the arse」と表現した。意訳すれば「面倒くさい代物」あたりだろうか。続けて、ウェイト分配から階層的なピック処理まで「全部ダメだ」と書いている。

重み分配で問題が始まり、階層的なピックで終わる。すべてが酷い。

開発者本人が自分の管轄領域をここまで率直にこき下ろす場面は、そうそう見られるものではない。sched: Flatten the pickと名付けられたパッチシリーズが、その歪みに対する答えとして提示された。

階層を「平らに潰す」発想

問題の所在は、cgroup階層の深さにある。タスクをグループ化して優先度を割り振る仕組みは、コンテナやcgroup v2の普及で日常的に使われるようになった。一方、スケジューラはタスクを選ぶたびに階層を上から下まで降りていく必要があり、コア数が増えれば増えるほどコストが膨らんでいた。

ゼイルストラの解法は、シンプルかつ過激だ。階層的なロードトラッキングは残しつつ、実際に走らせる候補(runnable entities)を単一の平らな層に集める。enqueuepicktickの3つのタイミングで重みを再計算し、深い階層を毎回辿る作業から解放する。

cpusetからスケジューラ本体までの変更行数は、追加672行・削除656行。差し引きほぼゼロという数字が、これは新機能ではなく「作り直し」だと物語っている。

パッチ変更行数(ファイル別)
変更行数合計:追加672行 / 削除656行 / 8ファイル
※ git diff --statの「変更行数」(追加+削除の合計に類する数値)。fair.cが全体の85%超を占める。

「ポテト」での実験が示した数字

理屈はわかった。では実際に動かしたらどうなるのか。ここでゼイルストラ本人が行った「ちょっとした実験」が、技術記事としては異例のインパクトを持つ。

テスト用に、口語的にポテトと呼ばれるマシンを引っ張り出した。RX 580を積んだ古き良きSandybridge 2600k、GOGから買ったShadows: Awakensを動かす。1080pで普段はそれなりに快適に動くタイトルだ。

Intel Core i7-2600Kは2011年初頭のCPU。RX 580は2017年のミドルレンジGPU。どちらも現役と呼ぶには厳しい構成で、ゼイルストラ自身が「potato(ポテト=しょぼい)」と呼んでいる。

そこに、論理CPUごとに1つずつnice spin.shを走らせて意図的にCPUを締め上げる。8コピーの妨害プロセスを抱えた状態で、ゲームのFPSとフレームタイムを測定した。

結果は以下の通りだ。

Shadows: Awakens(GOG) ベンチマーク比較
指標 デフォルト スライス変更 変化
FPS
最小
3.8 20.6 約5.4倍
FPS
平均
48.0 57.2 +19%
FPS
最大
87.4 80.3 −8%
FT
最小(ms)
9.4 8.4 −11%
FT
平均(ms)
34.5 19.5 −43%
FT
最大(ms)
107.4 37.2 −65%
※ FPSは高いほど良い、FT(フレームタイム)は低いほど良い。検証機はCore i7-2600K + Radeon RX 580、CPUに8プロセスの`nice spin.sh`を並走させた高負荷条件。

注目はFPS最小値だ。3.8から20.6へ。約5.4倍 に跳ね上がっている。最大値こそ若干落ちているが、ゲーム体験を決めるのは平均でも最大でもなく、カクついた瞬間の最小値だ。プレイ可能ラインの境目で、まったく別物になっている。

なぜFPS最大値だけが下がったのか

数字をよく見ると、最大FPSは87.4から80.3へとわずかに下がっている。ピーク性能と安定性のトレードオフが、ここに表れているように見える。

スケジューラは、ある瞬間に1つのタスクに全力を出させるか、複数タスクで均等に分けるかを選ぶ。従来の仕組みは「ハマったときは超速いが、ハマらないと激遅」という挙動だった。フラット化後は、ピーク時の集中力を少し削る代わりに、悪条件でも下に落ちない振る舞いに変わっている。

ゲームに限った話ではない。コンテナで何十ものワークロードが同居するサーバー環境でも、同じ性質の改善が効くはずだ。誰か1人が独占して残りが餓える状況から、全員がそこそこ進む状況へ。スケジューラの設計思想として、後者のほうが現代的だと言える。

v1からv2への変更が物語ること

このパッチシリーズはv2であり、3月のv1から「Sashikoものいくつか」と「current tipへのリベース」と記されている。Sashiko(刺し子)はおそらく細部の繕いを指す内輪ジョークで、コアの設計は据え置きだ。

引用ブロックで紹介すべき要点を整理する。

15年前のSandy BridgeとRX 580という構成で、CPU高負荷時のゲームFPS最小値が3.8から20.6へ。最大値は微減(87.4→80.3)だが、最小値と平均フレームタイムの大幅改善でプレイ体験は別物になる。

v1から数カ月かけてのv2投稿は、レビュアーからのフィードバックを取り込んだ証拠でもある。スケジューラのような中核コードは、コードレビューを通る前に何度も寝かされる。それでもメインラインに入るまでには、まだ何往復もやり取りが必要になるはずだ。

メインライン入りの可能性と、その先

このパッチシリーズが次のマージウィンドウに入るかは、現時点では未定だ。Linuxカーネルのスケジューラ変更は、影響範囲があまりにも広い。サーバー、デスクトップ、組み込み、すべてに影響する。

それでも、開発者本人が「最悪だ」と呼ぶコードを作り直す動きが進んでいる事実は重要だ。スケジューラは保守的になりがちな領域で、「壊れていないなら触るな」が支配する。今回はメンテナ自身が「壊れている」と認めた上での再設計だ。

古いマシンを使い続けたい人にとっては、朗報だろう。新しいGPUを買えない、新しいCPUを買う気もない、でもゲームはしたい。そういうユーザーが、カーネルの更新だけで救われる日が来るかもしれない。

ペーター・ゼイルストラが「ポテト」と呼んだ自分のSandy Bridgeに、もう一度息を吹き込もうとしている。古いハードを使い続ける選択が罰ゲームでなくなる日は、案外近いのかもしれない。


参照元

関連記事

この記事を共有する