reference:
https://baijiahao.baidu.com/s?id=1592330790387359245&wfr=spider&for=pc
https://www.cnblogs.com/LubinLew/p/cpu_affinity.html
1、CPU亲和性(cpu affinity)
CPU affinity 是一种调度属性(scheduler property), 它可以将一个进程"绑定" 到一个或一组CPU上.
在SMP(Symmetric Multi-Processing对称多处理)架构下,Linux调度器(scheduler)会根据CPU affinity的设置让指定的进程运行在"绑定"的CPU上,而不会在别的CPU上运行.
Linux调度器同样支持自然CPU亲和性(natural CPU affinity): 调度器会试图保持进程在相同的CPU上运行, 这意味着进程通常不会在处理器之间频繁迁移,进程迁移的频率小就意味着产生的负载小。
因为程序的作者比调度器更了解程序,所以我们可以手动地为其分配CPU核,而不会过多地占用CPU0,或是让我们关键进程和一堆别的进程挤在一起,所有设置CPU亲和性可以使某些程序提高性能。
CPU affinity 使用位掩码(bitmask)表示, 每一位都表示一个CPU, 置1表示"绑定"。最低位表示第一个逻辑CPU, 最高位表示最后一个逻辑CPU
CPU affinity典型的表示方法是使用16进制,具体如下.
0x00000001 is processor #0
0x00000003 is processors #0 and #1
0xFFFFFFFF is all processors (#0 through #31)
2、为什么要指定进程在固定的cpu上运行
由于各个cpu都有自己的缓存,如L1,L2等,程序中的指令在CPU内部,往往通过分支预测,提前放到了流水线上。也就是说,一个进程在cpuA上运行时,其未来要执行的指令往往被cpuA预估了,会把未来要执行的指令提前写到自己的一、二级缓存中。当进程换到了cpuB运行后,除了cpuA上的之前做的缓存白做之外,还要把这些缓存丢弃以避免不要影响新的进程,而且cpuB为了提速,还需要重新做一次缓存,即使可以把cpuA的缓存拷贝到cpuB中,这样在电路间也很麻烦,而且也不能保证两个cpu之间的缓存规格一样,万一大小不同,该怎样截断,都是问题,因此不如到了那边重建。
因此,保证进程在同一个cpu上运行,可减少在cpu之间切换时产生的“原来缓存丢弃与重建新缓存”的损失。
3、查看进程运行在哪个逻辑cpu上
ps -eo pid,args,psr
(这里应该显示的是该进程中,tid(lwp)和pid相等的那个线程运行在哪个cpu上)
4、查看某个进程的每个线程运行在哪个逻辑cpu上
ps -To 'pid,lwp,psr,cmd' -p PID
(同一个进程中,不同线程的lwp是唯一的,但是不同进程之间,可能存在相同的lwp;当一个进程只有一个线程时,pid和lwp总是相同的)
5、查看和设置CPU亲和性
1) 使用指定的CPU亲和性运行一个新程序
taskset [-c] mask command [arg]...
举例:使用CPU0运行ls命令显示/etc/init.d下的所有内容
taskset -c 0 ls -al /etc/init.d/
2) 显示已经运行的进程的CPU亲和性
taskset -p pid
举例:查看init进程(PID=1)的CPU亲和性
taskset -p 1
3) 改变已经运行进程的CPU亲和力
taskset -p[c] mask pid
举例:打开2个终端,在第一个终端运行top命令,第二个终端中
首先运行:[~]# ps -eo pid,args,psr | grep top #获取top命令的pid和其所运行的CPU号
其次运行:[~]# taskset -cp 新的CPU号 pid #更改top命令运行的CPU号
最后运行:[~]# ps -eo pid,args,psr | grep top #查看是否更改成功
mast可以是一个cpu号,也可以是多个
taskset -cp 10 pid (运行在10号cpu上)
taskset -cp 10,12 pid (运行在10和12号cpu上)
taskset -cp 10-12 pid (运行在10\11\12号cpu上)
(改变已经启动的进程的cpu affinity,设置之后不是立刻生效的,似乎要等一小会,十几秒的样子?)
(固定在不同的线程也可能会造成性能损失,比如https://stackoverflow.com/questions/39495136/why-settting-cpu-affinity-make-threads-run-slower#中提到的情况)
(此外在我的系统(4.15.0-43-generic #46~16.04.1-Ubuntu SMP)上,还观察到了这个现象:如果通过taskset启动进程,该进程的所有线程都是跑在指定cpu上的,如果是启动之后再用taskset去改,就只有主线程的cpu会固定为指定cpu)
另外如果想通过隔离cpu达到更好的cpu控制效果,可以参考https://blog.csdn.net/tang05505622334/article/details/96477552
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)