我有一台 40 V 核心机器,其中运行着 java 进程。可以看到这个进程一直在cpu6上运行。
$watch ps -o pid,psr,comm -p 4076
Every 2.0s: ps -o pid,psr,comm -p 4076 Mon Apr 11 02:24:12 2016
PID PSR COMMAND
4076 6 java
$ sudo taskset -c -p 4076
pid 4076's current affinity list: 0-39
$ sudo taskset -p 4076
pid 4076's current affinity mask: ffffffffff
这是 CPU 利用率的 top 命令的样子
$ top -c
top - 02:27:37 up 47 days, 10:49, 9 users, load average: 2.83, 2.89, 3.01
Tasks: 470 total, 1 running, 469 sleeping, 0 stopped, 0 zombie
%Cpu0 : 36.0 us, 8.3 sy, 0.0 ni, 40.7 id, 8.7 wa, 0.0 hi, 6.3 si, 0.0 st
%Cpu1 : 1.3 us, 0.7 sy, 0.0 ni, 97.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.7 us, 0.7 sy, 0.0 ni, 98.0 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 1.4 us, 1.0 sy, 0.0 ni, 97.3 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 1.0 us, 1.3 sy, 0.0 ni, 97.0 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 0.3 us, 0.3 sy, 0.0 ni, 99.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu8 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu9 : 1.0 us, 1.0 sy, 0.0 ni, 97.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu10 : 0.7 us, 0.7 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu11 : 0.7 us, 0.0 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu12 : 0.7 us, 1.3 sy, 0.0 ni, 97.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu13 : 0.3 us, 0.7 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu14 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu15 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu16 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu17 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu18 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu19 : 1.7 us, 0.3 sy, 0.0 ni, 97.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu20 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu21 : 0.7 us, 0.0 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu22 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu23 : 0.7 us, 0.3 sy, 0.0 ni, 98.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu24 : 1.3 us, 0.7 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu25 : 2.0 us, 0.3 sy, 0.0 ni, 97.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu26 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu27 : 0.3 us, 0.7 sy, 0.0 ni, 98.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu28 : 0.3 us, 0.7 sy, 0.0 ni, 98.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu29 : 0.7 us, 0.7 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu30 : 1.0 us, 0.3 sy, 0.0 ni, 98.3 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu31 : 1.0 us, 0.7 sy, 0.0 ni, 98.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu32 : 0.7 us, 0.0 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu33 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu34 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu35 : 0.7 us, 0.0 sy, 0.0 ni, 99.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu36 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
正如您在 top 命令中看到的那样,CPU6 大部分时间处于空闲状态。因此可以在同一处理器上调度进程,这将有助于减少缓存失效。但是调度程序是如何完成这一切的呢?它是否跟踪每个进程及其最后执行的处理器?
答案1
是的,Linux 的调度程序会跟踪每个线程上次调度的位置,并且如果可以的话,倾向于将线程保留在同一 CPU 上。您猜到了原因:将线程从一个 CPU 迁移到另一个 CPU 比将其保留在同一 CPU 上的成本更高。还有更多内容:调度程序了解多个级别的缓存一致性,并尝试不要将线程迁移得太远:在同一个超线程核心内移动线程非常便宜,移动到同一 CPU 芯片上的另一个核心则不太便宜,转移到另一个 CPU 芯片会更昂贵,等等。用于此目的的工具是调度域。