进程的 CPU 亲和性掩码决定了它有资格运行的 CPU 集。在多处理器系统上,设置 CPU 亲和性掩码可用于获得性能优势。例如,通过将一个 CPU 专用于特定进程(即,设置该进程的亲和性掩码以指定单个 CPU,并将所有其他进程的亲和性掩码设置为排除该 CPU),可以确保该进程的最大执行速度。将进程限制在单个 CPU 上运行还可以避免由于进程停止在一个 CPU 上执行然后在另一个 CPU 上重新开始执行时发生的缓存失效而导致的性能成本。
CPU 亲和性掩码由cpu_set_t结构表示,一个“CPU 集”,由mask指向。提供了四个宏来操作 CPU 集。CPU_ZERO() 清除一个集。CPU_SET() 和CPU_CLR() 分别将给定的 CPU 添加到和从一个集中移除。CPU_ISSET() 测试以查看 CPU 是否是该集的一部分;这在sched_getaffinity() 返回后很有用。系统上第一个可用的 CPU 对应于cpu值为 0,下一个 CPU 对应于cpu值为 1,依此类推。常量CPU_SETSIZE (1024) 指定了一个大于可以存储在 CPU 集中的最大 CPU 编号的值。
sched_setaffinity() 将 ID 为pid的进程的 CPU 亲和性掩码设置为mask指定的值。如果pid为零,则使用调用进程。参数cpusetsize是指向mask的数据的长度(以字节为单位)。通常,此参数将指定为sizeof(cpu_set_t)。
如果由pid指定的进程当前未在mask中指定的 CPU 之一上运行,则该进程将迁移到mask中指定的 CPU 之一。
sched_getaffinity() 将 ID 为pid的进程的亲和性掩码写入mask指向的cpu_set_t结构中。cpusetsize参数指定mask的大小(以字节为单位)。如果pid为零,则返回调用进程的掩码。
通过fork(2) 创建的子进程继承其父进程的 CPU 亲和性掩码。亲和性掩码在execve(2) 中保留。
本手册页描述了 CPU 亲和性调用的 glibc 接口。实际的系统调用接口略有不同,mask的类型为unsigned long *,反映了 CPU 集的底层实现是一个简单的位掩码这一事实。成功时,原始sched_getaffinity() 系统调用返回内核内部用于表示 CPU 集位掩码的cpumask_t数据类型的 size(以字节为单位)。
历史
CPU 亲和性系统调用是在 Linux 内核 2.5.8 中引入的。库接口是在 glibc 2.3 中引入的。最初,glibc 接口包含一个cpusetsize参数。在 glibc 2.3.2 中,cpusetsize参数被删除,但此参数在 glibc 2.3.4 中被恢复。