获取进程和线程的CPU核心号

当你在 多核 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)。

发表评论

邮箱地址不会被公开。 必填项已用*标注