可以使用sched_setaffinity
将线程固定到cpu,从而提高性能(在某些情况下)
从linux手册页:
此外,如果我希望获得更实时的响应,则可以将该线程的调度程序策略更改为SCHED_FIFO
,并将优先级提高到某个较高的值(最高sched_get_priority_max
),这意味着有问题的线程应始终抢占其他线程准备就绪时,线程在其cpu上运行。
但是,在这一点上,运行在刚刚被实时线程抢占的cpu上的线程可能已经淘汰了许多实时线程的1级缓存条目。
我的问题如下:
最佳答案
答案是使用cpusets。 python cpuset utility使配置它们变得容易。
基本概念
3个cpusets
root
:存在于所有配置中,并包含所有cpus(非屏蔽)system
:包含用于系统任务的cpus-需要运行但不是“重要”(未屏蔽)的user
:包含用于“重要”任务的cpus-我们要在“实时”模式下运行的(屏蔽)shield
命令管理这3个cpuset。在安装过程中,它将所有可移动任务移动到非屏蔽cpuset(
system
)中,在拆卸期间,将所有可移动任务移动到root
cpuset中。设置完成后,该子命令使您可以将任务移动到shield(
user
)cpuset中,此外,还可以将特殊任务(内核线程)从root
移至system
(因此也移出user
cpuset)。命令:
首先,我们创建一个盾牌。自然,防护罩的布局将取决于机器/任务。例如,假设我们有一台4核非NUMA机器:我们想将 3核专用于屏蔽,而将 1核专用于无关紧要的任务;因为它不是NUMA,所以我们不需要指定任何内存节点参数,并且让内核线程在
root
cpuset中运行(即:跨所有cpus)$ cset shield --cpu 1-3
可以将某些内核线程(那些未绑定(bind)到特定CPU的线程)移到
system
cpuset中。 (通常,移动已绑定(bind)到特定CPU的内核线程不是一个好主意)$ cset shield --kthread on
现在,让我们列出屏蔽(
user
)或非屏蔽(system
)cpusets中正在运行的内容:( verbt的-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
-这些使您可以更好地控制cpuset设置
创建,调整,重命名,移动和销毁cpuset
指令
使用cpus 1-3创建一个cpuset,使用NUMA节点1并将其命名为“my_cpuset1”
$ cset set --cpu=1-3 --mem=1 --set=my_cpuset1
将“my_cpuset1”更改为仅使用CPU 1和CPU 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
列出现有的CPU集(级别1的深度)
$ cset set --list
列出现有的cpuset及其子级
$ cset set --list --set=my_cpuset1
列出所有现有的CPU
$ cset set --list --recurse
过程
管理线程和流程
指令
列出在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
将所有任务从一个CPU移动到另一个
$ 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创建优先分组
system
cpuset prio_low
cpusetprio_met
cpuset prio_high
cpusetprio_all
cpuset(请注意与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
关于linux - 如何屏蔽Linux调度程序中的CPU(防止将线程调度到该CPU上)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11111852/