当你在 多核 NUMA 处理器上运行需要较高性能的 HPC(高性能计算)程序或非常消耗网络资源的程序时,CPU/memory 的亲和力是限度其发挥最大性能的重要因素之一。在同一 NUMA 节点上调度最相关的进程可以减少缓慢的远程内存访问。像英特尔 Sandy Bridge 处理器,该处理器有一个集成的 PCIe 控制器,你可以在同一 NUMA 节点上调度网络 I/O 负载(如网卡)来突破 PCI 到 CPU 亲和力限制。
作为性能优化和故障排除的一部分,你可能想知道特定的进程/线程被调度到哪个 CPU 内核(或 NUMA 节点)上运行。
方法一:taskset命令
如果一个进程使用 taskset 命令明确的被固定(pinned)到 CPU 的特定内核上,你可以使用 taskset 命令找出被固定的 CPU 内核:
-p 表示指定pid进程号,这里可以改为指定的线程号,则展示对应的线程CPU
-c 显示cpu核心编号
$ taskset -pc $PID
例如, 如果你对 PID 3382206 这个进程有兴趣,但是,如果你没有明确固定进程到任何 CPU 内核,你会得到类似下面的亲和力列表。
$ taskset -pc 3382206
pid 3382206's current affinity list: 0-63
输出表明该进程可能会被安排在从0到63中的任何一个 CPU 内核。在这种情况下,taskset 不能识别该进程当前被分配给哪个 CPU 内核,你应该使用如下所述的方法。
方法二: ps命令
ps 命令可以告诉你每个进程/线程目前分配到的 (在“PSR”列)CPU ID。
- e 或者A,选择所有的进程
- L 显示线程信息
- F 显示该线程使用CPU核心序号
- o 显示自定义格式,pid表示进程号, psr表示使用cpu核心, comm表示执行的命令
# 获取精简信息,某个pid的所有线程所在cpu核心,$PID表示进程号,通过ps -ef获取
$ ps -L -o pid,psr,comm -p $PID
# 获取详细信息,某个pid的所有线程所在cpu核心,$PID表示进程名称
$ ps -eLF |grep $ProcName
输出表示进程的 PID 为 3382206 (名为"gobgpd")目前在CPU 内核 多个核心 上运行着。如果该过程没有被固定,PSR 列会根据内核可能调度该进程到不同内核而改变显示。
$ ps -L -o pid,psr,comm -p 3382206
PID PSR COMMAND
3382206 3 gobgpd
3382206 18 gobgpd
3382206 44 gobgpd
3382206 37 gobgpd
3382206 0 gobgpd
3382206 3 gobgpd
3382206 16 gobgpd
3382206 55 gobgpd
3382206 55 gobgpd
$ ps -eLF |head -n 1 && ps -eLF |grep gobgpd
UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD
root 3382205 1 3382205 0 1 53460 3264 33 Nov07 ? 00:00:00 /bin/sh -c env GOTRACEBACK=crash /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml >> /var/log/gobgpd/gobgpd/gobgpd.log 2>&1
root 3382206 3382205 3382206 0 56 181805 38700 3 Nov07 ? 00:00:00 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382207 0 56 181805 38700 54 Nov07 ? 00:17:56 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382208 0 56 181805 38700 32 Nov07 ? 02:05:04 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382209 0 56 181805 38700 37 Nov07 ? 00:00:00 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382210 0 56 181805 38700 43 Nov07 ? 02:00:19 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382211 0 56 181805 38700 3 Nov07 ? 00:00:00 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382212 0 56 181805 38700 39 Nov07 ? 02:13:38 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382213 0 56 181805 38700 61 Nov07 ? 02:10:16 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3382214 0 56 181805 38700 51 Nov07 ? 02:02:46 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
root 3382206 3382205 3384377 0 56 181805 38700 43 Nov07 ? 02:04:30 /usr/bin/gobgpd -t yaml -f /etc/gobgpd/gobgpd.yaml
# 如果需要其时刻变化,可以采用watch命令观察gobgpd程序其CPU核心动态变化;
$ watch -d -n1 'ps -eLF |head -n 1 && ps -eLF |grep gobgpd'
方法三:top命令
top 命令也可以显示 CPU 被分配给哪个进程。首先,在top 命令中使用“f”选项。然后按键,显示中会出现 "Last used CPU" 列,按'd'或空格键表示选择显示该列信息,最后按'q'或'Esc'退出。目前使用的 CPU 内核将出现在 “P”(或“PSR”)列下。
# 查看系统进程的线程及统计信息
$ top -H -p 3382206
Threads: 56 total, 0 running, 56 sleeping, 0 stopped, 0 zombie
%Cpu(s): 40.3 us, 0.2 sy, 0.0 ni, 59.2 id, 0.0 wa, 0.2 hi, 0.1 si, 0.0 st
MiB Mem : 514140.2 total, 299469.3 free, 209229.4 used, 5441.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 297778.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND P
3382213 root 20 0 727220 38372 11228 S 0.7 0.0 130:17.39 gobgpd 49
3382214 root 20 0 727220 38372 11228 S 0.7 0.0 122:47.50 gobgpd 1
3385696 root 20 0 727220 38372 11228 S 0.7 0.0 128:24.04 gobgpd 47
3385703 root 20 0 727220 38372 11228 S 0.7 0.0 92:25.60 gobgpd 38
3385714 root 20 0 727220 38372 11228 S 0.7 0.0 128:49.98 gobgpd 50
2182525 root 20 0 727220 38372 11228 S 0.7 0.0 120:21.70 gobgpd 51
3382207 root 20 0 727220 38372 11228 S 0.3 0.0 17:56.33 gobgpd 0
3382208 root 20 0 727220 38372 11228 S 0.3 0.0 125:05.96 gobgpd 39
3384377 root 20 0 727220 38372 11228 S 0.3 0.0 124:31.75 gobgpd 38
3385577 root 20 0 727220 38372 11228 S 0.3 0.0 135:28.93 gobgpd 60
3385689 root 20 0 727220 38372 11228 S 0.3 0.0 122:16.70 gobgpd 48
3385690 root 20 0 727220 38372 11228 S 0.3 0.0 122:30.68 gobgpd 41
获知Linux的进程运行在哪个CPU内核上的方法;相比于 ps 命令,使用 top 命令的好处是,你可以连续监视随着时间的改变, CPU 是如何分配的。
方法四: htop命令
#安装命令
$ yum install -y htop
#运行命令
$ htop
htop可以检查一个进程/线程当前使用的是哪个 CPU 内核的方法是使用 htop 命令。
从命令行启动 htop。按 键'F2'或者'C',然后进入"Columns",在"Available Columns"下会添加 PROCESSOR,'F5'按钮为加入。
每个进程当前使用的 CPU ID 将出现在“CPU”列中。
获知Linux的进程运行在哪个CPU内核上的方法
请注意,所有以前使用的命令 taskset,ps 和 top 分配CPU 内核的 IDs 为 0,1,2,...,N-1。然而,htop 分配 CPU 内核 IDs 从 1开始(直到 N)。