如何在 Linux 上的特定 CPU 内核上运行程序或进程
随着多核 CPU 在服务器级硬件以及最终用户台式电脑或笔记本电脑上变得越来越流行,社区中(例如,在编程模型、编译器或操作系统支持方面)越来越多地致力于开发针对多核架构优化的应用程序。
一种经常被用来在多核处理器上运行性能关键型应用程序的操作系统 (OS) 支持称为“处理器关联”或“CPU 固定”。这是操作系统特定的功能,将正在运行的进程或程序绑定到特定的 CPU 内核。
将程序绑定到特定的 CPU 内核在多种情况下可能会很有用。例如,当具有高度缓存限制工作负载的应用程序与其他 CPU 密集型作业一起运行时,将应用程序固定到特定 CPU 将减少 CPU 缓存未命中。此外,当两个进程通过共享内存进行密集通信时,将两个进程调度到同一 NUMA 域中的内核上将提高其性能。
本教程介绍如何在 Linux 上的特定 CPU 内核上运行程序或进程。
要将特定的 CPU 核心分配给程序或进程,您可以使用 taskset
,这是一个命令行工具,用于在 Linux 上检索或设置进程的 CPU 关联性。
在 Linux 上安装 taskset
taskset
工具是 Linux 中 util-linux
软件包的一部分,大多数 Linux 发行版默认都预安装了该软件包。如果 taskset
在您的 Linux 系统上不可用(例如在最小的 Docker 容器中),请按如下方式安装它。
Install taskset
on Debian, Ubuntu or Linux Mint
$ sudo apt-get install util-linux
Install taskset
on CentOS, Fedora or RHEL
$ sudo yum install util-linux
查看正在运行的进程的 CPU 亲和性
$ sudo apt-get install util-linux
Install taskset
on CentOS, Fedora or RHEL
$ sudo yum install util-linux
查看正在运行的进程的 CPU 亲和性
要检索进程的 CPU 关联性信息,请使用以下命令。请注意,taskset
以十六进制位掩码格式返回当前 CPU 关联性。
$ taskset -p <PID>
例如,要检查 PID 2915 的进程的 CPU 亲和性:
$ taskset -p 2915
pid 2915's current affinity mask: ff
在此示例中,返回的关联性(以十六进制位掩码表示)对应于二进制格式的 11111111
,这意味着该进程可以在八个不同的 CPU 核心(从 0 到 7)中的任何一个上运行。
十六进制位掩码中的最低位对应于核心 ID 0,从右侧数第二低位对应于核心 ID 1,第三低位对应于核心 ID 2,等等。例如,CPU 亲和性 0x11
代表 CPU 核心 0 和 4。
taskset
可以将 CPU 关联性显示为处理器列表而不是位掩码,这样更易于阅读。要使用此格式,请使用 -c
选项运行 taskset
。例如:
$ taskset -cp 2915
pid 2915's current affinity list: 0-7
将正在运行的进程固定到特定的 CPU 内核
使用taskset
,您可以固定(或分配)正在运行的进程到特定的CPU 核心。为此,请使用以下命令。
$ taskset -p <COREMASK> <PID>
$ taskset -cp <CORE-LIST> <PID>
例如,要将进程分配给 CPU 核心 0 和 4,请执行以下操作。
$ taskset -p 0x11 9030
pid 9030's current affinity mask: ff
pid 9030's new affinity mask: 11
或者等价地:
$ taskset -cp 0,4 9030
使用 -c
选项,您可以指定以逗号分隔的数字 CPU 核心 ID 列表,甚至包括范围(例如 0,2,5,6-10)。
请注意,为了能够更改进程的 CPU 关联性,用户必须具有 CAP_SYS_NICE 能力。任何用户都可以查看进程的关联掩码。
在特定 CPU 内核上启动程序
taskset
还允许您启动固定到特定 CPU 核心的新程序。为此,请使用以下命令。
$ taskset <COREMASK> <EXECUTABLE>
例如,要在 CPU 核心 0 上启动 vlc
程序,请使用以下命令。
$ taskset 0x1 vlc
将整个 CPU 核心专用于特定程序
虽然任务集允许将特定程序分配给某些 CPU,但这并不意味着不会在这些 CPU 上调度其他程序或进程。如果您想防止这种情况并将整个 CPU 核心专用于特定程序,您可以使用 isolcpus 内核参数,该参数允许您在启动期间保留 CPU 核心。
在引导过程中将内核参数 isolcpus=
添加到引导加载程序或 GRUB 配置文件中。然后,Linux 调度程序将不会在保留的 CPU 核心上调度任何常规进程,除非使用 taskset
特别请求。例如,要保留 CPU 核心 0 和 1,请添加 isolcpus=0,1
内核参数。启动后,然后使用 taskset
将保留的 CPU 核心安全地分配给您的程序。