答案是:使用
cpusets。
python cpuset utility使其易于配置。
基本概念
3个cpusets
root
:包含所有CPU(未屏蔽的),在所有配置中都存在
system
:包含用于系统任务的CPU - 那些需要运行但不是“重要”的任务(未屏蔽的)
user
:包含用于“重要”任务的CPU - 那些我们想以“实时”模式运行的任务(屏蔽的)
shield
命令管理这3个cpusets。
在安装期间,它将所有可移动的任务移动到未屏蔽的cpuset(system
),并在拆卸期间将所有可移动的任务移动到root
cpuset 中。
安装完成后,子命令允许您将任务移动到shield(user
)cpuset中,并且还可以将特殊任务(内核线程)从root
移动到system
(因此从user
cpuset中移除)。
命令:
首先,我们创建一个屏蔽。自然情况下,屏蔽的布局将取决于机器/任务。例如,假设我们有一个4核非NUMA机器:我们要将 3个内核分配给屏蔽,并留下 1个内核用于不重要的任务;由于它是非NUMA,因此我们不需要指定任何内存节点参数,并且在root
cpuset(即跨所有CPU)中运行内核线程。
$ cset shield --cpu 1-3
一些内核线程(那些没有绑定到特定CPU的线程)可以被移动到system
cpuset中。(通常情况下,将已绑定到特定CPU的内核线程移动是不明智的。)
$ cset shield --kthread on
现在让我们列出在受保护的(user
)或未受保护的(system
) cpuset中正在运行的内容: (使用-v
可以列出进程名称)(添加第二个-v
以显示超过80个字符)
$ cset shield --shield -v
$ cset shield --unshield -v -v
如果我们想要停止屏蔽(拆卸)
$ cset shield --reset
现在让我们在保护模式下执行一个进程(在 '--'
后面的命令将传递给要执行的命令,而不是 cset
)
$ cset shield --exec mycommand -- -arg1 -arg2
如果我们已经有一个正在运行的进程,想要将其移动到盾牌中(注意,我们可以通过传递逗号分隔的列表或范围来移动多个进程(范围内的任何进程都将被移动,即使存在间隔))
$ cset shield --shield --pid 1234
$ cset shield --shield --pid 1234,1236
$ cset shield --shield --pid 1234,1237,1238-1240
高级概念
cset set/proc
- 这些命令可以更精细地控制cpusets
集合
创建、调整、重命名、移动和销毁cpusets
命令
使用cpu 1-3,使用NUMA节点1创建一个名为"my_cpuset1"的cpuset
$ cset set --cpu=1-3 --mem=1 --set=my_cpuset1
将"my_cpuset1"更改为仅使用CPU 1和3
$ cset set --cpu=1,3 --mem=1 --set=my_cpuset1
销毁一个cpuset
$ cset set --destroy --set=my_cpuset1
重命名现有的cpuset
$ cset set --set=my_cpuset1 --newname=your_cpuset1
创建一个分层的cpuset。
$ cset set --cpu=3 --mem=1 --set=my_cpuset1/my_subset1
$ cset set --list
列出当前cpuset及其子节点。
$ cset set --list --set=my_cpuset1
列出所有现有的cpuset。
$ cset set --list --recurse
Proc
管理线程和进程
命令
列出在cpuset中运行的任务
$ cset proc --list --set=my_cpuset1 --verbose
在cpuset中执行任务
$ cset proc --set=my_cpuset1 --exec myApp -- --arg1 --arg2
移动任务
$ cset proc --toset=my_cpuset1 --move --pid 1234
$ cset proc --toset=my_cpuset1 --move --pid 1234,1236
$ cset proc --toset=my_cpuset1 --move --pid 1238-1340
移动一个任务及其所有兄弟任务
$ cset proc --move --toset=my_cpuset1 --pid 1234 --threads
将所有任务从一个cpuset移动到另一个cpuset
$ cset proc --move --fromset=my_cpuset1 --toset=system
将未固定的内核线程移动到一个cpuset中
$ cset proc --kthread --fromset=root --toset=system
将内核线程(包括那些被固定到特定CPU上的线程)强制转移到一个cpuset中(注意:这可能会对系统产生严重后果 - 确保您知道您在做什么)
$ cset proc --kthread --fromset=root --toset=system --force
层级示例
我们可以使用分层cpusets创建优先级分组。
- 创建具有1个cpu(0)的
system
cpuset。
- 创建具有1个cpu(1)的
prio_low
cpuset。
- 创建具有2个cpu(1-2)的
prio_met
cpuset。
- 创建具有3个cpu(1-3)的
prio_high
cpuset。
- 创建具有所有4个cpu(0-3)的
prio_all
cpuset(请注意,这与root相同;将其与root分离是一个良好的实践)。
为了实现上述目标,您需要创建prio_all,然后在其中创建子集prio_high等。
$ cset set --cpu=0 --set=system
$ cset set --cpu=0-3 --set=prio_all
$ cset set --cpu=1-3 --set=/prio_all/prio_high
$ cset set --cpu=1-2 --set=/prio_all/prio_high/prio_med
$ cset set --cpu=1 --set=/prio_all/prio_high/prio_med/prio_low