第二讲:多核架构基础 — ARM big.LITTLE、DynamIQ 与 Exynos 的 CPU 集群设计
各位同学,今天我们聊点硬核的。多核架构,说白了就是芯片怎么把一堆 CPU 核组织起来干活。你想想看,手机里既要跑微信、又要刷抖音、还得挂个游戏后台,单核早就扛不住了。那 ARM 是怎么解决这个问题的?big.LITTLE 架构就是第一个真正落地的方案。
2.1 ARM big.LITTLE 架构:大小核的由来
big.LITTLE 这个概念,我记得是 2011 年左右 ARM 正式推出来的。当时大家还在争论「核多就一定强吗」,ARM 直接甩了个组合拳:大核(Cortex-A 系列)负责重活,小核(Cortex-A 系列的低功耗版本)处理轻任务。
为什么要这么搞?因为功耗。大核跑高频时功耗飙升,但手机电池就那么点容量。小核虽然性能弱,但省电啊。你想想看,待机时用小核,打游戏时切大核,这不就平衡了?
核心要点: big.LITTLE 不是简单的「大+小」,而是通过硬件一致性总线(CCI/CMN)让大小核共享内存,任务可以在核间无缝迁移。
我在项目中遇到过一个问题:某款平板用 big.LITTLE 方案,切核时总卡顿。后来发现是内核调度器没配好,迁移延迟太高。嗯,这里要提醒大家,硬件只是基础,软件调度才是灵魂。
2.2 DynamIQ 技术:big.LITTLE 的进化版
2017 年,ARM 推出了 DynamIQ 技术。说白了,它把 big.LITTLE 的「两簇」结构升级成了「多簇灵活组合」。以前你只能一组大核+一组小核,现在可以搞 1+3+4 甚至 1+2+5 这种奇葩配置。
DynamIQ 最大的改进是什么?我总结三点:
- 更细的粒度: 每个核可以独立调频调压,不像以前整簇一起调
- 更快的迁移: 核间通信延迟从微秒级降到纳秒级
- 更灵活的集群: 支持 Cortex-X 超大核 + Cortex-A 大核 + Cortex-A 小核混搭
个人经验: 我调试过一款基于 DynamIQ 的芯片,发现小核跑轻负载时,如果频率压得太低,反而会因为任务排队时间变长而更耗电。所以调优时别光看「频率越低越省电」,得看实际吞吐量。
2.3 Exynos 的 CPU 集群设计:Cortex-X / Cortex-A / Cortex-M
三星 Exynos 系列,尤其是 2200 和 2400 这两代,把 DynamIQ 玩出了花。它们采用了「三集群」设计:
| 集群类型 | 核心型号 | 典型数量 | 主要用途 |
|---|---|---|---|
| 超大核集群 | Cortex-X2/X3 | 1 个 | 游戏、渲染、AI 推理等高负载场景 |
| 大核集群 | Cortex-A710/A720 | 3-4 个 | 日常应用、多任务切换 |
| 小核集群 | Cortex-A510/A520 | 4 个 | 待机、后台任务、轻量服务 |
为什么 Exynos 要搞三个集群?我个人的理解是:为了更精细的功耗控制。你想想看,打游戏时只需要超大核发力,刷微博时大核就够了,待机时全切到小核。如果只有大小两簇,中间地带就浪费了。
避坑指南: 我曾经调试 Exynos 2200 时发现,Cortex-X 超大核如果长时间跑在最高频,芯片温度会迅速飙升,然后触发降频。结果就是「刚爽了 30 秒,后面全程卡顿」。所以调度策略里一定要加「温度感知」逻辑,别傻乎乎地一直怼高频。
2.4 集群间的通信与一致性
多核架构最头疼的问题是什么?缓存一致性。大核改了数据,小核不知道,那就乱套了。ARM 的解决方案是 CCI(Cache Coherent Interconnect)和后来的 CMN(Coherent Mesh Network)。
Exynos 用的是 CMN-700 互连架构。它把 CPU 核、GPU、NPU 都挂在一个 mesh 网络上,通过 snoop filter 来跟踪缓存状态。说白了,就是每个核改数据时,互连网络会广播通知其他核:「嘿,你缓存里的那行数据过期了!」
这里有个性能陷阱:如果频繁跨核共享数据,snoop 开销会很大。我建议你在写多核代码时,尽量让每个核处理独立的数据集,别搞太多共享变量。
2.5 调度器眼中的多核架构
从 Linux 调度器的角度看,Exynos 的三集群结构长什么样?嗯,它会被抽象成三个调度域(sched domain):
- MC 域: 同一个集群内的核,共享 L2 缓存,调度开销最小
- DIE 域: 不同集群之间,需要通过 CMN 互连,调度开销稍大
- NUMA 域: 如果芯片有多个 DIE(比如 Exynos 2400 的某些变体),跨 DIE 调度延迟更高
我调试过一个场景:某个后台服务被调度到了小核集群,但它的工作负载其实需要大核性能。结果就是任务执行时间翻倍,用户感觉手机卡顿。后来我加了「任务类型标签」,让调度器根据负载特征自动选择集群。
关键结论: 多核架构的优化,本质上是「在正确的时间,把正确的任务,放到正确的核上」。硬件给了你三集群的武器,但怎么用,还得看调度策略。
2.6 实战:如何查看 Exynos 的集群拓扑
在 Linux 系统里,你可以通过 /sys/devices/system/cpu/ 来查看集群信息。比如:
# 查看 CPU 拓扑
cat /sys/devices/system/cpu/cpu*/topology/core_id
# 查看集群编号(cluster_id)
cat /sys/devices/system/cpu/cpu*/topology/cluster_id
# 查看 CPU 频率范围
cat /sys/devices/system/cpu/cpufreq/policy*/scaling_available_frequencies
我个人习惯先跑一遍 lscpu -e,看看每个核的 cluster 归属。然后结合 cpuidle 信息,判断哪些核是「小核」(通常 idle 状态更深)。
小技巧: 如果你发现某个核的 cluster_id 是 0,那它大概率是超大核或大核。cluster_id 越大,通常对应越省电的核。但不同芯片的映射规则不一样,最好查一下 datasheet。
2.7 总结与思考
这一章我们聊了 big.LITTLE 的起源、DynamIQ 的进化、Exynos 的三集群设计,以及调度器怎么看待这些硬件。说白了,多核架构就是一场「性能与功耗的博弈」。ARM 给了你三把刀(X/A/M),但怎么挥刀,还得看你的调度策略。
下一章,我们会深入 Linux 调度器的源码,看看 CFS 和 EAS 是怎么在 Exynos 上做任务分配的。到时候我会拿一个真实的性能调优案例来拆解,保证干货满满。
嗯,今天就到这里。有问题随时在群里问我,或者翻翻我公众号「蓝海资料掘金营」的历史文章,里面有不少调度相关的实战笔记。