进程、线程绑定cpu核的问题,在这里将所学记录一下。高通骁龙采用1+3+4的超独特设计,Prime超大核、3个Kryo Gold核心和4个Kryo Silver核心。
其中0-3是Silver核芯,4-6是Gold核心,7是Prime超大核。
绑定核心的方法
通过bash指令绑定
这里以绑定Silver核0~3核为例:
cd /dev/cpuset/top-app/
echo 0-3 > cpus
通过sched_setaffinity函数来实现
与进程的情况相似,线程亲和性的设置和获取主要通过下面函数来实现:
#include <unistd.h>
int sched_setaffinity(pthread_tthread, size_tcpusetsize, const cpu_set_t *cpuset);
//初始化,设为空
void CPU_ZERO (cpu_set_t *set);
//将某个cpu加入cpu集中
void CPU_SET (int cpu, cpu_set_t *set);
//将某个cpu从cpu集中移出
void CPU_CLR (int cpu, cpu_set_t *set);
//判断某个cpu是否已在cpu集中设置了
int CPU_ISSET (int cpu, const cpu_set_t *set);
以下为核心代码:
cpu_set_t mask; //CPU核的集合
cpu_set_t get; //获取在集合中的CPU
int num = num = sysconf(_SC_NPROCESSORS_CONF); //获取核数
CPU_ZERO(&mask); //置空
if (bindConfig == "prime")
{
CPU_SET(7,&mask); //设置亲和力值
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
{
LOGD("warning: could not set CPU affinity, continuing...");
}
}
else if (bindConfig == "gold")
{
CPU_SET(4,&mask); //设置亲和力值
CPU_SET(5,&mask); //设置亲和力值
CPU_SET(6,&mask); //设置亲和力值
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
{
LOGD("warning: could not set CPU affinity, continuing...");
}
}
else if (bindConfig == "silver")
{
CPU_SET(0,&mask); //设置亲和力值
CPU_SET(1,&mask); //设置亲和力值
CPU_SET(2,&mask); //设置亲和力值
CPU_SET(3,&mask); //设置亲和力值
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
{
LOGD("warning: could not set CPU affinity, continuing...");
}
}
else
{
CPU_SET(0,&mask); //设置亲和力值
CPU_SET(1,&mask); //设置亲和力值
CPU_SET(2,&mask); //设置亲和力值
CPU_SET(3,&mask); //设置亲和力值
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
{
LOGD("warning: could not set CPU affinity, continuing...");
}
}
cpu集可以认为是一个掩码,每个设置的位都对应一个可以合法调度的 cpu,而未设置的位则对应一个不可调度的 CPU。换而言之,线程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了,也就是可以在所有的cpu中调度。
查看绑定那个核心
adb shell top | grep ${程序名}
会输出对应程序号,同时通过这个可以查看程序的CPU占用率
taskset -p pid ${程序号}
便可以看到核心的掩码
例如:掩码为cpu mask=0x70即3个Gold大核
cpu mask=0xf即四个Silver小核