Linux kernel: process management - CPU affinity setting

1. Get the number of CPU cores

int CPU_NUM = sysconf(_SC_NPROCESSORS_CONF);

2. Threads are bound to CPU cores

① concept

CPU binding  refers to binding a process or thread to a specified CPU core for execution in a multi-CPU system. In Linux, we can use the CPU affinity (affinity) attribute to bind a process to one or more CPU cores.

CPU Affinity  is an attribute of a process, which indicates which CPUs the process scheduler can schedule the process to.
This property requires a process to run on a specified CPU for as long as possible without being migrated to another processor.

There are two types of CPU Affinity:

  • soft affinity
  • hard affinity

Soft affinity  is just a suggestion. If it is unavoidable, the scheduler will still schedule the process to other CPUs for execution;

Hard affinity  is a rule that the scheduler must abide by. The Linux kernel of version 2.6 or above allows developers to program to achieve hard affinity.

② function

The binding between process and CPU  In Linux, a structure is used cpu_set_tto represent the CPU Affinity mask, and a series of macros are defined to operate the set of schedulable CPUs of the process:

#define _GNU_SOURCE

#include <sched.h>

void CPU_ZERO(cpu_set_t *set); // 清除集合的内容,让其不包含任何 CPU。
void CPU_SET(int cpu, cpu_set_t *set); // 添加 CPU 到集合中
void CPU_CLR(int cpu, cpu_set_t *set); // 从集合中移除 CPU
int CPU_ISSET(int cpu, cpu_set_t *set); // 测试 CPU 是否在集合中
int CPU_COUNT(cpu_set_t *set); // 返回集合中包含的 CPU 数量

In Linux, the following two functions can be used  to set and get the CPU Affinity property of a process:

#define _GNU_SOURCE

#include <sched.h>

/**
 * 进程与 CPU 的绑定
 * 
 * 该函数设置进程为 pid 的这个进程,让它运行在 mask 所设定的 CPU 上.
 * 1. 如果 pid 的值为 0, 则表示指定的是当前进程, 使当前进程运行在mask所设定的那些 CPU 上
 * 2. 第二个参数 cpusetsize 是 mask 所指定的数的长度. 通常设定为 sizeof(cpu_set_t). 
 *    如果当前 pid 所指定的进程此时没有运行在 mask 所指定的任意一个 CPU 上, 则该指定的
 *    进程会从其它 CPU 上迁移到 mask 的指定的一个 CPU 上运行. 
 * 3. mask 为 CPU 核集合
*/
int sched_setaffinity(pid_t pid, size_t cpusetsize,const cpu_set_t *mask);

/**
 * 该函数获得 pid 所指示的进程的 CPU 位掩码, 并将该掩码返回到 mask 所指向的结构中.
 * 即获得指定 pid 当前可以运行在哪些 CPU 上. 同样,如果 pid 的值为 0. 也表示的是当前进程
*/
int sched_getaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);

/**
 * 线程与 CPU 的绑定
*/
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);

In addition, the following function can be used to know which CPU the current process is running on:

int sched_getcpu(void);

If the call is successful, the function returns a non-negative CPU number value.

③ example

The following function binds different processes to different cores according to the different values ​​entered when different processes are called, so as to utilize the multi-core of the CPU

void func(int i) {
    cpu_set_t mask;
    CPU_ZERO(&mask);
    int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
    if (cpu_num == 0) {
    	cpu_num = 1;
    }
    CPU_SET((i % cpu_num), &mask);
    sched_setaffinity(0, sizeof(cpu_set_t), &mask);
}

Kernel information through train: Linux kernel source code technology learning route + video tutorial code information

Learning through train: Linux kernel source code/memory tuning/file system/process management/device driver/network protocol stack

Original Author: Proficient in Linux Kernel

Original address: Linux Kernel: Process Management - CPU Affinity Setting - Zhihu (Copyright belongs to the author of the original text, please contact to delete the infringement message)

 

おすすめ

転載: blog.csdn.net/m0_74282605/article/details/130117424