LinuxにおけるCPU割当制御

# 1.概要
Linux は処理が集中した CPU から空いているCPU にプロセスをマイグレーションするスケジュール機能が備わっている。それにより複数のプロセスが動作していると他のプロセスの処理にCPUが使用され性能に影響が出ることがある。
しかしisolcpusオプションを使用することで、kernelのCPU割り当て可能リストから除外することが可能となる。CPU割り当て可能リストから除外したCPUに対してプロセスを割り当てることで他のプロセスの影響を受けずに処理を行うことができる。

# 2.isolcpus設定手順
## 手順1:grubファイルの修正
◆対象ファイル
・/etc/default/grub
◆修正対象キー
・GRUB_CMDLINE_LINUX_DEFAULT
◆追加内容
・isolcpus=対象CPUコア番号
※複数の場合は「,」区切り、連番の場合は「-」で記載
※記載例
以下はCPUコア2、5、6、7、8、9、10を
kernelのスケジューリングから除外する設定の例

```grub
GRUB_CMDLINE_LINUX_DEFAULT=“isolcpus=2,5-10”
```

## 手順2:grubファイルの更新
◆Ubuntuの場合
・sudo update-grub
◆RedHatの場合
・sudo grub2-mkconfig -o /etc/grub2.cfg

## 手順3:grubファイルの反映
grubファイルの反映のため、マシンのリブートを行う。
・sudo reboot

# 3.コマンド
コマンドによるプロセスに割り当たっているCPUの確認方法、プロセスへのCPU割り当て方法は以下の通り。

## 割り当たっているCPU確認
### ホスト
・taskset –c –p pid
-c:CPUコア番号をリストで表示
-p:指定したPIDの割り当てを表示
※表示例

```
[abc@localhost ~]$ taskset -c -p 20572
pid 20572's current affinity list: 0-3
```

※-cオプション無しの表示例

```
[abc@localhost ~]$ taskset -p 20572
pid 20572's current affinity mask: f
```
### VM
・sudo virsh vcpuinfo VM名
※表示例
※CPUアフィニティーの数はCPUのコア数分表示される
※CPUアフィニティーは割り当たっている場合「y」、
割り当たっていない場合「-」が表示される。

```
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm1
VCPU: 0
CPU: 0
状態: 実行中
CPU 時間: 2975.3s
CPU アフィニティー: yyyy

VCPU: 1
CPU: 1
状態: 実行中
CPU 時間: 2621.6s
CPU アフィニティー: yyyy
```

## プロセスへのCPU割り当て
### ホスト
・taskset –c –p 割り当てCPUコア番号 pid
-c:CPUコア番号をリストで表示
-p:指定したPIDにCPUを割り当て
※表示例

```
[abc@localhost ~]$ taskset -c -p 1 20572
pid 20572's current affinity list: 0-3
pid 20572's new affinity list: 1
```

※-cオプション無しの表示例

```
[abc@localhost ~]$ taskset -p 1 20721
pid 20721's current affinity mask: f
pid 20721's new affinity mask: 1
```

### VM
・sudo virsh vcpupin VM名 vcpu cpuコア番号
※表示例

```
[abc@localhost ~]$ sudo virsh vcpupin abc-vm1 0 2
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm1
VCPU: 0
CPU: 2
状態: 実行中
CPU 時間: 2983.3s
CPU アフィニティー: --y-

VCPU: 1
CPU: 2
状態: 実行中
CPU 時間: 2629.5s
CPU アフィニティー: yyyy
```

# 4.xml設定手順(VM用)
VM起動時にCPU割り当てを実施するためのxmlの設定手順は以下の通り。

## 設定手順

1. VM停止
    2. sudo virsh shutdown VM名
    3. ※VMが停止済みの場合は不要
4. xml定義編集
    5. sudo virsh edit VM名
6. VM起動
    7. sudo virsh start VM名


### 全VCPUにまとめて設定
設定対象キー:vcpu
設定値:cpuset=“CPUコア番号”
※但し、vcpupinが設定されている場合はvcpupinの設定が優先され、
vcpuによるCPU割り当ては無効となる。

※設定例
CPUコア番号3を割り当てる例を以下に示す。

```
<domain type='kvm'>
<name>abc-vm2</name>
・・・
<vcpu placement='static' cpuset='3'>4</vcpu>
・・・
```

※表示例
・cpuset未設定

```
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm2
VCPU: 0
CPU: 2
状態: 実行中
CPU 時間: 1994.4s
CPU アフィニティー: yyyy

VCPU: 1
CPU: 0
状態: 実行中
CPU 時間: 1677.9s
CPU アフィニティー: yyyy
```


・cpuset設定

```
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm2
VCPU: 0
CPU: 3
状態: 実行中
CPU 時間: 8.1s
CPU アフィニティー: ---y

VCPU: 1
CPU: 3
状態: 実行中
CPU 時間: 2.4s
CPU アフィニティー: ---y
```

### VCPUに個別設定
設定対象キー:vcpupin
設定値:vcpu=“VCPU番号” cpuset=“CPUコア番号”
※設定例
VCPU0にCPUコア番号3をVCPU1にCPUコア番号1を
割り当てる例を以下に示す。

```
<domain type='kvm'>
<name>abc-vm2</name>
<vcpu placement='static'>4</vcpu>
・・・
<cputune>
<vcpupin vcpu='0' cpuset='3'/>
<vcpupin vcpu='1' cpuset='1'/>
</cputune>
・・・
```

※表示例
・vcpupin未設定

```
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm2
VCPU: 0
CPU: 2
状態: 実行中
CPU 時間: 1994.4s
CPU アフィニティー: yyyy

VCPU: 1
CPU: 0
状態: 実行中
CPU 時間: 1677.9s
CPU アフィニティー: yyyy
```


・vcpupin設定

```
[abc@localhost ~]$ sudo virsh vcpuinfo abc-vm2
VCPU: 0
CPU: 3
状態: 実行中
CPU 時間: 7.1s
CPU アフィニティー: ---y

VCPU: 1
CPU: 1
状態: 実行中
CPU 時間: 0.6s
CPU アフィニティー: -y--
```

# 参考
- [[Linux] Isolate CPU](https://www.nminoru.jp/~nminoru/diary/2012/07.html#20120712p1)