答案是使用cpusets http://www.kernel.org/doc/man-pages/online/pages/man7/cpuset.7.html. The python cpuset实用程序 http://code.google.com/p/cpuset/使配置它们变得容易。
基本概念
3个CPU组
-
root
:存在于所有配置中并包含所有 cpu(未屏蔽的)
-
system
:包含用于系统任务的CPU - 需要运行但不“重要”的CPU(未屏蔽的)
-
user
:包含用于“重要”任务的CPU - 我们想要在“实时”模式下运行的任务(shielded)
The shield
命令管理这 3 个 cpuset。
在设置过程中,它将所有可移动任务移至非屏蔽 cpuset 中(system
)并且在拆卸期间它将所有可移动任务移至root
cpuset。
设置完成后,子命令可让您将任务移至shield (user
) cpuset,此外,还可以将特殊任务(内核线程)从root
to system
(因此从user
中央处理器组)。
命令:
首先我们创建一个盾牌。当然,防护罩的布局将取决于机器/任务。例如,假设我们有一台 4 核非 NUMA 机器:我们想要专用3 芯到屏蔽, 然后离开1 个核心用于执行不重要的任务;因为它是非 NUMA,所以我们不需要指定任何内存节点参数,并且我们让内核线程在root
cpuset(即:跨所有 cpu)
$ cset shield --cpu 1-3
一些内核线程(那些未绑定到特定 cpu 的线程)可以移至system
cpuset。 (一般来说,移动已绑定到特定 cpu 的内核线程并不是一个好主意)
$ cset shield --kthread on
现在让我们列出盾牌中正在运行的内容(user
)或非屏蔽(system
) CPU 组: (-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
Set
创建、调整、重命名、移动和销毁CPU组
Commands
创建一个cpuset,使用cpus 1-3,使用NUMA节点1并将其命名为“my_cpuset1”
$ cset set --cpu=1-3 --mem=1 --set=my_cpuset1
将“my_cpuset1”更改为仅使用 cpus 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
列出现有的 cpuset(级别 1 的深度)
$ cset set --list
列出现有的 cpuset 及其子项
$ cset set --list --set=my_cpuset1
列出所有现有的 cpuset
$ cset set --list --recurse
Proc
管理线程和进程
Commands
列出 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
层次结构示例
我们可以使用分层 cpuset 来创建优先级分组
- 创建一个
system
具有 1 个 cpu 的 cpuset (0)
- 创建一个
prio_low
具有 1 个 cpu 的 cpuset (1)
- 创建一个
prio_met
具有 2 个 cpu 的 cpuset (1-2)
- 创建一个
prio_high
具有 3 个 cpu 的 cpuset (1-3)
- 创建一个
prio_all
具有所有 4 个 cpu (0-3) 的 cpuset(请注意,这与 root 相同;与 root 保持分离被认为是良好的做法)
为了实现上述目的,您创建 prio_all,然后在 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