CPU Isolation

きょうは Linux カーネルがユーザーランドプロセスにスケジューリングしないCPUを確保しておく方法についてです。これによってコンテナやVMに割り当てるためのCPUが、ホストOSのユーザランドプロセスに使われてしまうことを回避できます。

使うディストリビューションは Ubuntu 22.04 ですが、機能自体はカーネルに依存するので他のディストリビューションでも参考になるはずです。

それではまず、カーネルのブートパラメーターを設定します。 isolcpus とそのパラメーターとして cpu のリストをわたします。ここでは、 0-23 のコアのうち、 8-23 を分離します。

$ sudo vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash isolcpus=8-23"

そうしたら grub の設定を更新して再起動します。

$ sudo update-grub
$ sudo reboot

簡単ですね。では試してみましょう。 mpstat コマンドでコアごとの使用率をモニターします。入ってなかったらインストールしてください。

$ sudo apt install sysstat
$ mpstat -P ALL 1

そして別のターミナルから stress コマンドで 24 プロセスのストレッサーを起動します。

$ stress -c 24

CPU ID 8 から 23 は使用されていません。目的は達せられていますね。ただし、使い方によっては分離した CPU の特に sys 時間が消費されることがあります。試しに stress-ng コマンドで負荷をかけてみましょう。

$ stress-ng --class cpu --seq 0

分離した CPU もカーネルスペースからは使用されることがあるので、それは頭の片隅に入れて置く必要があります。

では、こんどは反対に分離した CPU を使ってみましょう。 taskset コマンドでプロセスに CPU を割り当てます。

$ taskset -c 15,16 stress -c 2

あれ、 2 つの CPU が使われると思いきや、 1 つしか使われませんね。どうやら使われるスケジューラによってこういう動作になるらしく、ためしてないけど VM ならたぶん起きないと思われます。コンテナは環境によっては起きそうな気もするので確認しましょう。ディストリビューションのカーネルチューニングによってもこの挙動は変わるはずです。明示的にスケジューラを指定してやると、 2 つの CPU が使われるようになりました。

sudo chrt -r 1 taskset -c 15,16 stress -c 2

そのほかの関連パラメータはこちら。調べるときの参考まで。

nohz_full=8-23
rcu_nocbs=8-23
irqaffinity=0

https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*