cpuset とは
cpuset は Cgroup サブシステムの 1 つで、特定のプロセスやスレッドが使用する CPU の組を指定する機能となる。また、メモリノードの割付も同様に行うことが可能。
スレッドを特定の CPU に割り付ける機能としては CPU affinity もあり、現在のカーネルでもサポートされているが、cpuset を使用することが推奨されている。
使い方
cpuset を使うためにはカーネルコンフィグで CONFIG_CPUSETS=y となっている必要があるが、最近のディストリビューションであれば標準で有効になっている。
cpuset は Cgroup サブシステムとして提供されているため、使用する場合は cgroup ファイルシステムをマウントする必要がある。
$ sudo mount -o cpuset -t cgroup cgroup /cgroup/
ここで、CPU 割り付けグループとして GroupA を作成し、GroupA の cpuset を編集して GroupA に割り付ける CPU を CPU0 だけにする。
なお、今回は簡単のため、複数の CPU コアが存在するマシンを使用する。
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 79
Model name: Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz
Stepping: 1
CPU MHz: 2300.093
BogoMIPS: 4600.10
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 46080K
NUMA node0 CPU(s): 0-7
$ sudo mkdir /cgroup/GroupA
$ sudo bash -c "echo 0 > /cgroup/GroupA/cpuset.cpus"
$ sudo bash -c "echo 0 > /cgroup/GroupA/cpuset.mems"
$ cat /cgroup/GroupA/cpuset.cpus
0
ちなみに、cpuset.mems でメモリノードも指定しないと tasks に PID 書き込んだ時に以下みたいに怒られる。
bash: line 0: echo: write error: No space left on device
ここまできたら、いつものようにシェルプロセスを GroupA に所属させ、CPU を 100% 使い切るような状態にする。
$ sudo bash -c "echo $$ > /cgroup/GroupA/tasks"
$ yes > /dev/null
この状態で以下のように mpstat でコア毎の CPU 使用率を見ると、確かに CPU0 のみが使用されていることがわかる。
$ mpstat -P ALL 10 1
Linux 4.14.77-70.59.amzn1.x86_64 (ip-10-1-11-189) 01/14/2020 _x86_64_ (8 CPU)
11:03:30 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
11:03:40 AM all 12.39 0.00 0.11 0.00 0.00 0.00 0.00 0.00 87.50
11:03:40 AM 0 99.10 0.00 0.90 0.00 0.00 0.00 0.00 0.00 0.00
11:03:40 AM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:03:40 AM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
Average: all 12.39 0.00 0.11 0.00 0.00 0.00 0.00 0.00 87.50
Average: 0 99.10 0.00 0.90 0.00 0.00 0.00 0.00 0.00 0.00
Average: 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
ここで、さらにシェルプロセスを 2 つ立ち上げ、同様に GroupA に所属させてから yes コマンドで CPU を使い切る。
$ cat /cgroup/GroupA/tasks
3122
3174
3262
3317
3321
3346
ただ、この状況でも mpstat の結果は変わらず。
$ mpstat -P ALL 10 1
Linux 4.14.77-70.59.amzn1.x86_64 (ip-10-1-11-189) 01/14/2020 _x86_64_ (8 CPU)
11:09:07 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
11:09:17 AM all 12.43 0.00 0.10 0.00 0.00 0.00 0.00 0.00 87.48
11:09:17 AM 0 99.20 0.00 0.80 0.00 0.00 0.00 0.00 0.00 0.00
11:09:17 AM 1 0.10 0.00 0.00 0.00 0.00 0.00 0.10 0.00 99.80
11:09:17 AM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:09:17 AM 3 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.90
11:09:17 AM 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:09:17 AM 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:09:17 AM 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
11:09:17 AM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
Average: all 12.43 0.00 0.10 0.00 0.00 0.00 0.00 0.00 87.48
Average: 0 99.20 0.00 0.80 0.00 0.00 0.00 0.00 0.00 0.00
Average: 1 0.10 0.00 0.00 0.00 0.00 0.00 0.10 0.00 99.80
Average: 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 3 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.90
Average: 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
ここで top を見るとそれぞれのプロセスが 33% 付近の値を記録しており、全て CPU0 に割り付けられていることがわかる。
top - 11:09:50 up 14 min, 5 users, load average: 2.28, 1.19, 0.56
Tasks: 146 total, 4 running, 91 sleeping, 0 stopped, 1 zombie
Cpu(s): 7.0%us, 0.1%sy, 0.0%ni, 92.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.5%st
Mem: 32941444k total, 270500k used, 32670944k free, 10580k buffers
Swap: 0k total, 0k used, 0k free, 109600k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3174 ec2-user 20 0 105m 1664 1568 R 33.8 0.0 7:16.78 yes
3346 ec2-user 20 0 105m 1748 1652 R 33.8 0.0 0:17.51 yes
3317 ec2-user 20 0 105m 1728 1632 R 31.8 0.0 0:28.16 yes