4. CPU子系统性能分析与调优
R-Car车载计算平台的CPU子系统通常由多个Cortex-A核(如A76/A55大小核组合)构成,运行Linux与实时任务混合负载。性能问题往往不是单一原因造成的:可能是某个核被单线程任务打满、可能是频率被热约束压低、也可能是任务在核间频繁迁移导致缓存失效。要定位并解决这些问题,需要把perf、ftrace、cpufreq/cpuidle、CPU hotplug和任务亲和性这几类工具组合起来使用,形成"观测—定位—干预—验证"的闭环。
用perf定位热点与调度行为
perf是CPU性能分析的第一入口。面对"系统变慢"这类模糊描述,先用perf stat看整体指标,再用perf top或perf record找热点函数。
# 采样5秒,观察整体CPU行为
perf stat -a -e cycles,instructions,cache-misses,context-switches,cpu-migrations sleep 5
# 记录热点,-g带调用栈
perf record -F 999 -g -a -- sleep 10
perf report --stdio | head -40
关键判读点:instructions per cycle(IPC)偏低说明CPU在等内存或分支预测失败;cache-misses高且伴随大量cpu-migrations,往往意味着任务在核间漂移、L1/L2缓存反复失效;context-switches异常高则可能是锁竞争或调度抖动。在R-Car这类大小核平台上,还要用perf stat -e cpu-clock --per-core分核观察,确认是某个A76核饱和,还是A55核被误调度了重负载。
用ftrace追踪调度延迟与唤醒路径
perf擅长统计,ftrace擅长看时序。当怀疑调度延迟或中断抖动时,用trace-cmd或直接操作tracefs抓取调度事件。
# 抓取调度切换与唤醒事件
echo 1 > /sys/kernel/debug/tracing/events/sched/enable
echo 1 > /sys/kernel/debug/tracing/events/irq/enable
echo function_graph > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/trace_pipe
重点看sched_wakeup到sched_switch之间的时间差,这就是任务的唤醒延迟。如果延迟达到毫秒级,常见原因是目标CPU正处于idle深睡状态(C-state退出慢),或该核被其他高优先级任务占用。配合sched_switch中的prev/next字段,可以还原出"谁抢占了谁",判断是否存在优先级反转或CPU争抢。
cpufreq与cpuidle:功耗与性能的平衡点
R-Car的CPU频率由cpufreq子系统管理,常见governor有schedutil、ondemand、performance。车载场景推荐schedutil,它直接依据调度器的利用率信号调频,响应比ondemand更快。
# 查看当前策略与可用频率
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
# 切换到schedutil并设置上下限
echo schedutil > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
echo 1200000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
cpuidle则控制核进入多深的睡眠。C-state越深省电越多,但退出延迟越大。如果ftrace显示唤醒延迟高,可以查看/sys/devices/system/cpu/cpu0/cpuidle/下各状态的latency与usage,必要时用cpuidle.governor=menu或限制最大C-state来降低延迟。功耗与延迟的取舍必须结合具体任务:安全相关的实时任务应避免深睡,而后台批处理任务则可以放宽。
任务亲和性与CPU hotplug
把关键任务绑定到固定核,可以避免迁移带来的缓存失效和延迟抖动。使用taskset或sched_setaffinity设置亲和性:
# 将PID 1234绑定到CPU 2和3
taskset -pc 2,3 1234
# 启动时直接绑定
taskset -c 2 ./adas_perception
在大小核平台上,通常把实时/高吞吐任务绑到A76大核,把轻量后台任务放到A55小核,减少互相干扰。CPU hotplug则用于动态上下线核心:在热约束或低负载时下线部分核以省电,但要注意下线前必须先把该核上的任务迁走,否则会触发迁移开销甚至失败。
# 下线CPU 3(需先确保无任务绑定)
echo 0 > /sys/devices/system/cpu/cpu3/online
下图总结了从观测到干预再到验证的完整分析链路,以及各工具在其中的作用位置。
综合调优示例与判断依据
假设某ADAS感知任务在R-Car上出现周期性卡顿。按上述链路:先用perf stat发现cpu-migrations偏高,再用ftrace看到任务在CPU 0~3之间反复迁移,且唤醒延迟约1.2ms。干预措施:将感知线程用taskset -c 4,5绑定到A76大核,把governor设为schedutil并锁定min_freq为1.2GHz,同时限制CPU 4/5的最大C-state为C1以降低唤醒延迟。验证时重新跑perf stat,若cpu-migrations降到接近0、唤醒延迟降到200μs以内、IPC提升,则说明调优有效;若功耗上升超出预算,则需在频率上限和C-state深度之间重新找平衡点。