序言
多线程程序运行在多核CPU上,如果不进行核心绑定,经检测,默认是使用所有核心来运行程序的。即使单线程程序,运行过程中也会切换CPU核心。
CPU核心绑定的方式
绑定CPU核心,即设置CPU亲和力或者设置处理器关系。在网上查了一些资料,比较常见的绑定CPU核心的方法主要是这两个:
命令/脚本实现方式:taskset
程序实现方式:
- 进程:sched_setaffinity
- 线程:pthread_setaffinity_np
1. taskset实现
taskset
简介:linux提供的一个命令,它可以让某个进程运行在某个/某些CPU核心上
使用情形:taskset设置CPU亲和力也分两种情况
- [1] 运行中设置:即知道了进程pid再进行绑定操作
- 这种方法的最大弊端就是不具有实时性
- [2] 启动时设置:即在程序开始执行时就进行绑定操作
- 这种方法对于适用于实时的性能测试
- [1] 运行中设置:即知道了进程pid再进行绑定操作
命令:
[1] 显示进程在用CPU
taskset -p pid
taskset -p 3652
pid 3652’s current affinity mask: ff = 1111的bitmask,表示进程3652在用的CPU,即四个核心都会使用
[2] 进程与特定CPU核心绑定
taskset -pc cpu_id pid
taskset -pc 3 2499
pid 2499’s current affinity list: 0-3
pid 2499’s new affinity list: 3表示程序绑定在第4个核心运行(从0开始计数)
[3] 进程启动时指定CPU
taskset -c 1 vlc
表示启动vlc并绑定在第2个核心运行,程序启动后查看各个线程的核心占用如下图(P表示正在使用的核心)
其他命令
taskset -c 0,5,7,9-11 vlc
- 表示启动vlc并绑定在0,5,7,9-11范围的核心运行
taskset -pc 0,3,7-11 700
- 表示将进程700与特定CPU核心list绑定
2. 程序实现
进程绑定到CPU
- Linux提供一个接口,可以将进程绑定到特定的CPU:
/* 头文件 */
#include <sched.h>
/* 函数 */
int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
参数
pid:进程的id号,如果pid为0,则表示本进程
cpusetsize:mask的大小
mask:运行进程的CPU,可以通过以下函数操作mask
#define CPU_SET(cpu, cpusetp) //设置cpu
#define CPU_CLR(cpu, cpusetp) //删除cpu
#define CPU_ISSET(cpu, cpusetp) //判断cpu
#define CPU_ZERO(cpusetp) //初始化为0
- 线程绑定到CPU
- Linux提供一个接口,可以将线程绑定到特定的CPU
- 该接口与进程绑定到CPU的接口的使用方法基本一致
- 注:当进程绑定到特定的CPU之后,线程还是可以绑定到其他的CPU的,没有冲突。
/* 头文件 */
#include <pthread.h>
/* 函数 */
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);
- 程序实现使用示例可参考:http://www.linuxidc.com/Linux/2015-04/116867.htm
Acknowledgements:
http://blog.csdn.net/vevenlcf/article/details/46842137
http://www.linuxidc.com/Linux/2015-04/116867.htm
2017.08.04