cpuset

January 14, 2020

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  

 © 2023, Dealing with Ambiguity