Genericカーネルに低遅延カーネルの機能を統合
「Ubuntu 24.04 LTS」の Generic カーネルに低遅延カーネルの機能が統合されました。- Fine-Tuning the Ubuntu 24.04 Kernel for low latency, throughput, and power efficiency
- Enable low latency features in the generic Ubuntu kernel for 24.04
Generic カーネル
その種類の1つに Generic カーネルがあります。
Generic という言葉が指すとおり、幅広い用途に使用される Linux Kernel であり、多くのPCでは Generic カーネルがインストールされています。
他にもクラウド向けや特定のハードウェア向けなど、Ubuntu ではそれぞれの用途や環境に最適化した Linux Kernel を提供しています。
Ubuntu ではこれらの Linux Kernel の種類のことを、カーネルバリアントと呼んでいます。
またこれらの Linux Kernel をカスタムカーネルと呼んでいます。
本来は Generic カーネルであらゆる環境をサポートできれば良いのですが、サポートの都合やリリースの都合等で Generic カーネルでその環境をサポートできない時に、その環境に対応したカーネルバリアントが登場することになります。
とはいえ Ubuntu では、カスタムカーネルに実装された固有の機能は、最終的に Generic カーネルへ還元するように取り組んでいます。
ちなみに Generic(ジェネリック)というと、汎用的や一般的など、なんとなく十分に最適化されていない凡庸な印象を持ちやすいかと思いますが、そんなことはありません。
Ubuntu における Generic カーネルは、あらゆるユースケースを対象としたカーネルとして位置づけられています。
低遅延カーネル
低遅延カーネルはバリアント(フレーバー)の1つ lowlatency のカスタムカーネルであり、応答性を重視したカーネルです。低遅延カーネルはサウンド処理など高度なマルチメディア環境で使用されるカーネルです。
DTMといった作業では入出力デバイスとの同期など、遅延が作業に影響を与えます。
低遅延カーネルは、このような作業環境で活用されるカスタムカーネルです。
今まで Ubuntu はこのようなユースケースを想定し、Generic カーネルと低遅延カーネルを両方提供してきました。
低遅延カーネルの機能を Generic カーネルへ
Ubuntu 24.04 LTS の Generic カーネルから、低遅延カーネルの機能が Generic カーネルに取り込まれ、 Generic カーネルでも低遅延カーネルの機能を利用できるようになりました。Ubuntu 24.04 LTS でも引き続き低遅延カーネルを提供していますが、将来的に低遅延カーネルは無くなる予定です。
これは Generic カーネルに低遅延カーネルの機能が取り込まれたことで、低遅延カーネルでできることは Generic カーネルでも全く同じことができるようになったためです。
カーネルオプション
さて Generic カーネルでは低遅延の設定をオプションで調整できるようになっています。この設定は以下の3種類のカテゴリーに分けられます。
- Kernel Preemption Model
- Kernel Noise
- CPU Wake-up Events
Kernel Preemption Model
Kernel Preemption Model では、以下の3種類の設定を指定可能です。- preempt=full
- preempt=voluntary
- preempt=none
起動時の指定と動的な変更
これらの設定は Ubuntu 起動時にカーネルオプションとして指定する方法と、Ubuntu 起動後に動的に変更する方法があります。Ubuntu 起動後に動的に変更する場合、以下のファイルに設定を指定します。
- /sys/kernel/debug/sched/preempt
full
full 設定は、低遅延が高度に要求される環境でおすすめの設定です。例えばゲームやライブストリーミング、DTMや動画制作といったマルチメディア制作など、低遅延が要求される作業でこの設定を活用すると良いでしょう。
full 設定で高い優先度を持つタスクは、低い優先度を持つタスクに割り込んでCPUリソースを割り当ててもらえる機会が多くなります。
voluntary
voluntary 設定は full 設定よりもタスクに割り込む機会が減るため、full ほど高度な低遅延が要求されないが、高い計算パフォーマンスを維持したい環境でおすすめの設定です。例えば一般的なサーバーやハイパフォーマンス・コンピューティングでは、voluntary 設定が好ましいケースもあるでしょう。
none
none 設定は、CPUを集中的に利用し、I/Oが最小限の処理で効果が期待できる設定です。例えば複雑な画像処理や機械学習で効果を期待できるでしょう。
none 設定はこのように、ある特定の処理で効果が期待できる設定であり、それ以外のユースケースでは利点が得られにくい設定です。
Kernel Noise
割り込みによって発生するノイズは、遅延に大きな影響を受けるアプリのパフォーマンスやレスポンスの予測可能性に影響を与える可能性があります。この割り込みには、ハードウェア割り込みだけでなく、Tick 割り込みも含まれます。
Tick 割り込みは、時間の計測や利用、タスクスケジューリングで定期的に発生する割り込みです。
nohz_full=<CPU_LIST>
この設定は Ubuntu 起動時にカーネルオプションとして指定します。<CPU_LIST> に Tick 割り込みを無効化する CPU リストを指定します。
そのCPUで処理するタスクが1つ以下の時、 Tick 割り込みが無効になります。
結果アプリが利用可能なCPU時間が増えることになります。
IRQ Affinity設定との組み合わせでより効果的に
適切なIRQ Affinity設定を行うことで、CPUをあらゆる割り込みソースから隔離でき、そのCPU上で動作しているユーザースペースのアプリは、パフォーマンスの予測可能性を向上させることができます。CPU Wake-up Events
モダンなCPUの消費電力は、アイドル状態から復帰(ウェイクアップ)する頻度で大抵決まってきます。CPUのアイドル状態が長く続けば続くほど消費電力は抑えられ、バッテリーの残量が減りにくくなります。
割り込みや非同期イベントは、CPUをアイドル状態から復帰させる出来事(ウェイクアップイベント)であり、消費電力の増加に繋がります。
RCU
カーネルにとって RCU によって引き起こされるウェイクアップイベントは、RCU の非同期コールバックの実行により、アイドル状態から復帰させる機会が多く発生する可能性があり、その場合消費電力の増大に繋がります。ウェイクアップイベントの頻度抑制
このウェイクアップイベントの頻度を制御するカーネルオプションを利用できます。この設定は Ubuntu 起動時にカーネルオプションとして指定します。
- rcu_nocbs=<CPU_LIST>
- rcutree.enable_rcu_lazy=1
rcu_nocbs=<CPU_LIST> は RCU コールバックの実行を softirq コンテキストから kthread コンテキストに移します。
rcutree.enable_rcu_lazy=1 は即座に RCU コールバックを実行するのではなく、一定時間後にまとめて処理します。
これによりウェイクアップイベントの頻度が大幅に減り、約5% 〜 10% 程度の消費電力の節約が期待できます。
特にノートPCで効果的
バッテリーで動作するノートPCで上記の設定を組み合わせれば、電力効率の向上に期待できるでしょう。設定の組み合わせ例
上記で紹介した設定の組み合わせ例を紹介します。ちなみに上記で紹介した設定の内容は一般的な指標であり、特定のシナリオに合いそうな設定でも、十分な効果が期待できないケースもあります。
そのため設定の組み合わせごとに性能を評価することをおすすめします。
サーバー用途
- 何も変更せずデフォルトのまま
ゲーム用途
- preempt=full
仮想化用途
- preempt=full
- nohz_full=all
オーディオ用途
- preempt=full
- nohz_full=all
- threadirqs
ノートPCなどモバイル用途
- preempt=full
- rcu_nocbs=all
- rcutree.enable_rcu_lazy=1
設定を指定するには
カーネルオプションに設定を指定するには、以下の手順に沿ってください。- root で /etc/default/grub ファイルを開く
- GRUB_CMDLINE_LINUX_DEFAULT= に設定を1行かつ空白区切りで記述する
- sudo update-grub コマンドを実行する
- PCを再起動する
その他の低遅延設定
上記で紹介した設定以外にも、低遅延に有用な設定があります。1. cpufreq governor
cpufreq governor に performance を指定します。- /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
2. Proactive memory compaction の無効化
以下のコマンドで Proactive memory compaction を無効化できます。echo 0 | sudo tee /proc/sys/vm/compaction_proactiveness
3. Kernel samepage merging の無効化
以下のコマンドで Kernel samepage merging を無効化できます。echo 0 | sudo tee /sys/kernel/mm/ksm/run
4. ワーキングセットの削除遅延
以下のコマンドでワーキングセットの削除を指定した時間遅延できます。ここでは例として1,000ミリ秒を指定しています。
echo 1000 | sudo tee /sys/kernel/mm/lru_gen/min_ttl_ms
5. ページキャッシュのディスク書き込み制御
以下のコマンドでページキャッシュのディスク書き込みを制御できます。ここでは例として 5% を指定しています。
echo 5 | sudo tee /proc/sys/vm/dirty_ratio
echo 5 | sudo tee /proc/sys/vm/dirty_background_ratio
echo 5 | sudo tee /proc/sys/vm/dirty_background_ratio