一、概念
根据wikipedia上的解释,通过设置CPU亲和性可以控制线程在哪些CPU上运行。
CPU亲和性就是一个特定的任务要在某个给定的CPU上尽可能的长时间运行而不被迁移到其他处理器的倾向性,这也意味着进程或者线程不必在多个处理器之间频繁迁移。
通过CPU亲和性的概念可以提高线程的运行效率,比如由于CPU存在缓存机制,通过CPU亲和性(CPU Affinity)让同一个线程被重新调度时,尽量调度到同一个处理器上,这样就可以可以避免不必要的 Cache Miss。另一种情况,比如对于一组相同的任务,它们需要访问的内存大部分是相同的,如果控制这组任务调度在相同的CPU上,也可以共享相同的cache,从而提高程序的访问效率。
CPU亲和性分为2种,分别为软亲和性和硬亲和性:
- 软亲和性: linux系统会尽可能将一个进程保持在指定的CPU上运行,但不严格保证,当所指定的CPU非常繁忙时,它可以迁移到其他空闲CPU上执行
- 硬亲和性:linux系统允许指定某个进程运行在特定的一个或一组CPU上,并且只能运行在这些特定的CPU上。
使用hard affinity的意义
提高CPU缓存命中率
CPU各核之间是不共享缓存的,如果进程频繁地在多个CPU核之间切换,则会使旧CPU核的cache失效,失去了利用CPU缓存的优势。如果进程只在某个CPU上执行,可以避免进程在一个CPU上停止执行,然后在不同的CPU上重新执行时发生的缓存无效而引起的性能成本。
适合对时间敏感的应用
在实时性要求高应用中,我们可以把重要的系统进程绑定到指定的CPU上,把应用进程绑定到其余的CPU上。这种做法确保对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序使用其余的计算资源。
CPU绑核适应的情况
- 计算密集型的进程
- 运行时间敏感、核心的进程
二、绑核
1.taskset
taskset -p cpumask $pid
例如:
需要把renderthread固定到大核上:
taskset -p f0 $pid
2.native层
//设置线程或者进程在某个CPU上运行
sched_setaffinity(thread_id, sizeof(cpu_set), &cpu_set);
// 查看线程或者进程在哪一个CPU运行
sched_getaffinity()
//线程绑定到某个CPU Core
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);
3.java层 (nice值)
//进程优先级
setThreadPriority(int tid, int priority)
//线程优先级
setProcessGroup(int pid, int group)
setThreadGroup(int tid, int group)
//调度器选择
setThreadScheduler(int tid, int policy, int priority)
进程优先级(priority) | nice值 | prio值 | 名称 | 解释 |
THREAD_PRIORITY_DEFAULT | 0 | 120 | 默认 | Standard priority of application threads. |
THREAD_PRIORITY_MORE_FAVORABLE | -1 | 119 | 比默认高 | Minimum increment to make a priority more favorable. |
THREAD_PRIORITY_LESS_FAVORABLE | 1 | 121 | 比默认低 | Minimum increment to make a priority less favorable. |
THREAD_PRIORITY_LOWEST | 19 | 139 | 最低 | Lowest available thread priority. |
THREAD_PRIORITY_BACKGROUND | 10 | 130 | 后台 | Standard priority background threads. |
THREAD_PRIORITY_FOREGROUND | -2 | 118 | 前台 | Standard priority of threads that are currently running a user interface that the user is interacting with. |
THREAD_PRIORITY_DISPLAY | -4 | 116 | 显示 | Standard priority of system display threads, involved in updating the user interface. |
THREAD_PRIORITY_URGENT_DISPLAY | -8 | 112 | 显示(更为重要) | Standard priority of the most important display threads, for compositing the screen and retrieving input events. |
THREAD_PRIORITY_VIDEO | -10 | 110 | 视频 | Standard priority of video threads. |
THREAD_PRIORITY_TOP_APP_BOOST | -10 | 110 | 提频 | Priority we boost main thread and RT of top app to. |
THREAD_PRIORITY_AUDIO | -16 | 104 | 音频 | Standard priority of audio threads. |
THREAD_PRIORITY_URGENT_AUDIO | -19 | 101 | 音频(更为重要) | Standard priority of the most important audio threads. |
组优先级(group) | 取值 | 名称 | 解释 | |
THREAD_GROUP_DEFAULT | -1 | 默认 | Default thread group -has meaning with setProcessGroup() only, cannot be used with setThreadGroup(). | |
THREAD_GROUP_BG_NONINTERACTIVE | 0 | 后台 | Background thread group - All threads in this group are scheduled with a reduced share of the CPU. | |
THREAD_GROUP_FOREGROUND | 1 | 前台 | Foreground thread group - All threads in this group are scheduled with a normal share of the CPU. | |
THREAD_GROUP_SYSTEM | 2 | 系统 | System thread group. | |
THREAD_GROUP_AUDIO_APP | 3 | 应用程序音频 | Application audio thread group. | |
THREAD_GROUP_AUDIO_SYS | 4 | 系统程序音频 | System audio thread group. | |
THREAD_GROUP_TOP_APP | 5 | 前台应用 | Thread group for top foreground app. | |
THREAD_GROUP_RT_APP | 6 | RT应用 | Thread group for RT app. | |
THREAD_GROUP_RESTRICTED | 7 | 灭屏 | Thread group for bound foreground services that should have additional CPU restrictions during screen off | |
调度器(policy) | 取值 | 名称 | 解释 | |
SCHED_OTHER | 0 | 默认 | 标准round-robin分时共享策略 | |
SCHED_FIFO | 1 | 先进先出 | 实时调度策略 | |
SCHED_RR | 2 | 循环调度 | 实时调度策略 | |
SCHED_BATCH | 3 | 批处理调度 | 针对具有batch风格(批处理)进程的调度策略 | |
SCHED_IDLE | 5 | 空闲调度 | 针对优先级非常低的适合在后台运行的进程 | |
SCHED_RESET_ON_FORK | 0x40000000 | 重置子进程 | Reset scheduler choice on fork. |
三、查看是否绑核
1.taskset
taskset -p $pid //进程
taskset -ap $pid //线程
例如:
# taskset -p 715
pid 715's current affinity mask: f
0000 1111(0-3核,0在最低位)
2.cat status
cat /proc/$pid/status | grep Cpus_allowed
例如:
Goldfinch_NP_Pro:/ $ cat proc/1/status | grep Cpus_allowed
Cpus_allowed: ff
Cpus_allowed_list: 0-7
3.systrace
sched_select_task_rq
需要打开节点:
adb shell "echo 1 > /sys/kernel/tracing/events/scheduler/sched_select_task_rq/enable"
例如:
<idle>-0 (-----) [006] d.s3 455.535618: sched_select_task_rq: pid=1272 policy=0x00080001 pre-cpu=1 target=1 util=3 boost=12 mask=0xff prefer=0 cpu_prefer=0 flags=0
其中mask表示pid=1272的task允许运行的cpu。