ARM big.LITTLE

移动 SoC 如何平衡”高性能”与”长续航”这对根本矛盾?本文从 ARM big.LITTLE 的硬件架构出发,逐一拆解 Cluster 迁移、CPU 迁移、Global Task Scheduling 三种软件执行模型和五种任务迁移机制,完整揭示操作系统调度器在异构核心间做决策的底层逻辑。

1. 移动处理器的性能与功耗悖论

现代移动软件栈对处理器提出了相互矛盾的双重需求:一方面,游戏、视频渲染等场景需要极高的峰值性能;另一方面,音频播放、后台同步等低强度任务必须极度省电。传统设计的困境在于:单一微架构处理器不可能同时满足高性能和高能效这两端。用高性能核处理低强度任务会白白浪费能量、缩短电池续航;而在高性能场景中,核心又受制于热约束(thermal bounds)无法持续运行在最高频率。

ARM 给出的答案是 big.LITTLE 技术——将高能效”LITTLE”核心与高性能”big”核心耦合在同一系统中。它属于异构多处理(Heterogeneous Multi-Processing, HMP)的一种实现。

AMP, SMP和HMP的对比如下:

特征 AMP (Asymmetric Multi-Processing) SMP (Symmetric Multi-Processing) HMP (Heterogeneous Multi-Processing)
核心类型 可以完全不同 完全相同 不同性能等级(big + LITTLE)
指令集兼容性 可以不同(如 Cortex-A + Cortex-M) 一致(同一 ISA) 100% 一致(通常同为 ARMv8-A)
核心能力 差异很大 等价 有性能差异
Cache 一致性 通常不要求(也可能有) 必须支持一致性 通常全部核心在同一一致性域内
操作系统 每个核心可能运行独立 OS 所有核心运行同一 OS 镜像 所有核心运行同一 OS 镜像
调度方式 静态分配,软件决定任务在哪个核 OS 自动负载均衡 OS 根据性能/功耗选择核心
OS 视角 多个独立执行单元 多个等价 CPU 多个能力不同的 CPU
典型场景 Cortex-A + Cortex-M 8× Cortex-A53 4× Cortex-A53 + 2× Cortex-A73
任务迁移 通常不迁移 任意迁移 可以迁移,但需考虑代价
主要目标 分工协作 提升吞吐 平衡性能和功耗

核心前提是简洁的:big 和 LITTLE 共享相同的 ISA,软件同一份二进制可在两类核心上不加修改地运行。操作系统根据性能需求将线程动态分配到 big 或 LITTLE 核上——需要峰值性能时运行在 big 核上,其余大部分时间在 LITTLE 核上执行。

要理解操作系统如何做出这个”该用大核还是小核”的决策,我们必须先从硬件层面的耦合方式入手。


2. big.LITTLE 系统的物理架构

要理解操作系统调度器如何在 big 和 LITTLE 核心之间迁移任务,必须先了解底层硬件的三项基础设施:两种核心的 ISA 一致性如何保证软件兼容、Cache 一致性如何让数据迁移透明高效、以及中断控制器如何让中断在异构核心间自由路由。这三者分别对应软件兼容性、数据通路和事件分发——缺一不可。

2.1 核心组成与 ISA 一致性

big.LITTLE 系统中的两类核心共享相同的指令集架构(ISA),差异仅在于内部微架构——这种微架构层面的设计取舍赋予了它们截然不同的功耗和性能特征。所有核心硬件 Cache 一致,同一份应用二进制不经修改即可在任一类型核心上运行。

典型的配置以 Cortex-A7 作为 LITTLE 簇、Cortex-A15 作为 big 簇。LITTLE 簇负责处理音频播放、页面滚动、OS 事件等低强度、常驻后台的任务,big 簇则在游戏、视频处理等场景下投入运行。

2.2 硬件 Cache 一致性:CCI-400 的角色

在 big 和 LITTLE 簇之间迁移任务时,数据必须透明且高效地转移。如果缺乏硬件一致性支持,跨簇数据传输只能经过主存——这在速度和功耗上都是灾难,而且需要复杂的 cache 维护软件来保证数据正确。

ARM 通过 CoreLink CCI-400(Cache Coherent Interconnect)提供硬件一致性支持。CCI-400 实现了 MOESI 协议,使得大数据可以直接在参与核心的 L1 Cache 之间传输,无需经主存中转。

2.3 共享中断控制器:GIC-400

除了数据一致性,中断路由也是异构系统必须解决的硬件问题。当中断可以在任意核心上触发时,迁移中断目标核心需要:

  • CoreLink GIC-400(Generic Interrupt Controller):支持中断在选定的任意核心间迁移
  • 所有核心可以通过分布式中断控制器互相发信号

任务切换完全由 OS 调度器处理,对应用程序透明。

硬件提供了 Cache 一致性和中断可迁移性这两个基础能力。在此基础上,软件如何组织两类核心的协同工作,便有了三种不同的执行模型。


3. 三种软件执行模型

ARM 将 big.LITTLE 的软件执行模型分为两大类:迁移(Migration)全局任务调度(Global Task Scheduling)。其中迁移模型又可以细分为 Cluster 迁移和 CPU 迁移。

理解迁移模型的关键类比是 DVFS(Dynamic Voltage and Frequency Scaling)——迁移行为本质上可视为 DVFS 操作点过渡的自然延伸:负载增加时沿当前核心的 DVFS 曲线上行,当当前核心(或簇)达到最高操作点仍不够时,触发核心(或簇)迁移,在新的 DVFS 曲线上继续遍历操作点。

这种设计将迁移泛化为 DVFS 系统的一个高阶操作点——设计哲学上与已有电源管理框架完全兼容。

3.1 Cluster 迁移

Cluster Migration 是早期 big.LITTLE 系统采用的一种运行模式。在任意时刻,系统只选择一个簇(big 或 LITTLE)作为主要计算簇运行,另一个簇处于关闭或非调度状态。只有在簇切换的短暂过程中,两个簇可能同时处于过渡状态。

软件栈大部分时间运行在 LITTLE 簇上,仅在需要峰值性能时切换至 big 簇。这种模式要求两个簇具有相同数量的核心,因为切换过程本质上是两个对等 cluster 之间的整体替换。

Cluster Migration 的主要缺陷是无法处理非均衡负载。当簇内只有一个核心负载较高,而其他核心处于空闲状态时,Cluster Migration 仍然会进行整个簇级别切换,导致不必要的性能和功耗开销。

实例:非均衡负载导致的”过度升级”

1
2
3
4
5
6
7
8
9
场景:4 核 LITTLE 簇,其中一个核心运行视频解码(高负载),其余核心空闲

Cluster 迁移的行为:
步骤 1 — LITTLE 簇性能不足,达到当前 DVFS 上限
步骤 2 — 整体触发 Cluster 切换至 big 簇
步骤 3 — 整个 big 簇接管运行任务,视频解码迁移到对应的大核上继续执行
其余大核没有实际负载,但仍会带来额外的功耗开销

净效果:为了满足单个高负载任务的性能需求,整体启用了 big 簇资源

3.2 CPU 迁移(In Kernel Switcher)

CPU 迁移将粒度从”簇”细化到”核心对”:每个 big 核心与一个 LITTLE 核心组成一对。在任意时刻,每对中只有一个核心处于活跃状态,另一个核心被关闭或保持低功耗状态。

在 Linaro In Kernel Switcher(IKS)实现中,操作系统看到的是若干个逻辑 CPU,每个逻辑 CPU 的底层物理实现可以根据负载需求,在 big 和 LITTLE 核心之间切换。

与 Cluster 迁移的关键区别:

维度 Cluster 迁移 CPU 迁移
活跃核心 同一时刻只有一个簇工作 不同核心对可分别选择 big 或 LITTLE
拓扑支持 通常要求核心数量对称 支持非完全对称拓扑
粒度 整个簇 单个核心对
代表实现 Linaro In Kernel Switcher (IKS)

实例:3+2 非对称拓扑下的 CPU 迁移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
配置:2 个 big 核(Cortex-A15),3 个 LITTLE 核(Cortex-A7)

OS 视角:
逻辑核 0:LITTLE0 ↔ big0
逻辑核 1:LITTLE1 ↔ big1
逻辑核 2:仅包含 LITTLE2(无对应 big 核)

时刻 T0 — 低负载
逻辑核 0 — 活跃: LITTLE0,big0 关闭
逻辑核 1 — 活跃: LITTLE1,big1 关闭
逻辑核 2 — 活跃: LITTLE2

结果:
3 个逻辑核心均运行在 LITTLE 核心上


时刻 T1 — 逻辑核 0 负载升高
逻辑核 0:
LITTLE0 达到性能瓶颈
→ 触发 CPU 迁移
→ 上下文切换至 big0

结果:
逻辑核 0 — 活跃: big0
逻辑核 1 — 活跃: LITTLE1
逻辑核 2 — 活跃: LITTLE2

此时 big 和 LITTLE 核心可以同时工作

然而,CPU 迁移的一对一绑定约束限制了核心利用率:同一个核心对中的 big 和 LITTLE 不能同时运行。当 big 和 LITTLE 数量不匹配时,多出的核心无法参与迁移配对,无法获得异构切换带来的性能收益。

3.3 全局任务调度 (GTS)

ARM 将 big.LITTLE 的软件模型从早期的簇级迁移模型逐步演进到全局任务调度(Global Task Scheduling,GTS)。GTS 是 ARM big.LITTLE MP(Multi-Processing)方案中的核心调度思想。

GTS 的核心突破在于:

操作系统调度器开始感知 big 和 LITTLE 核心之间的计算能力差异,而不是将所有 CPU 视为同等性能的处理单元。

它通过统计线程运行历史和负载变化,估计每个线程的性能需求,并据此决定线程应该运行在哪类核心上。

例如:

Cortex-A15 大核的单线程性能高于 Cortex-A7 小核。调度器通过维护不同核心的性能容量信息,将线程负载转换为统一的容量指标:

1
2
3
4
5
6
7
8
9
10
11
12
13
         线程负载需求
|
v
+----------------+
| 调度器比较能力 |
+----------------+
/ \
/ \
v v
LITTLE 核心 big 核心
容量较低 容量较高

适合低负载 适合高负载

这样,调度器可以判断某个线程更适合运行在 LITTLE 核心还是 big 核心,而不是简单根据固定阈值进行核心切换。

GTS 相对迁移模型的三大优势:

  1. 拓扑自由:big 和 LITTLE 核心数量可以任意不等
  2. 全核心利用:当需要峰值性能时,所有核心(big + LITTLE)可以同时上线
  3. 隔离执行:可将 big 簇专用于计算密集型线程,LITTLE 簇处理后台服务和中断——这使得重量级计算任务能更快完成,因为没有额外的后台线程干扰。

中断也可以被定向到特定类型的核心——将高频系统中断绑定到 LITTLE 核,避免打断 big 核上的持续计算。GTS 确定了”按线程负载分配核心”的调度哲学,但具体的分配决策如何落地?big.LITTLE MP 通过五种不同场景触发的迁移机制来回答这个工程问题。


4. 五种任务迁移机制

big.LITTLE MP 调度器的根本任务是决定:每个软件线程应该运行在 LITTLE 核心还是 big 核心上。

4.1 迁移阈值

调度器通过比较每个线程的跟踪负载(tracked load)与两个可调阈值来做出迁移决策——上迁移阈值和下迁移阈值。

  • 上迁移阈值(up migration threshold):当前运行在 LITTLE 核心上的线程,其跟踪负载超过此阈值 → 判定为应从 LITTLE 迁移到 big
  • 下迁移阈值(down migration threshold):当前运行在 big 核心上的线程,其跟踪负载低于此阈值 → 判定为应从 big 迁移到 LITTLE

这两个阈值之间存在明显的滞后(hysteresis)间隙——如上迁移阈值为 80%、下迁移阈值为 20%。这种设计防止了负载在阈值边界附近波动时引发频繁的迁移振荡(ping-pong effect)。当一个线程的负载从 79% 升到 81% 再降到 79% 时,如果没有滞后间隙,调度器会在两个核心之间来回迁移该线程——每次迁移都伴随着上下文保存/恢复和 cache 重新填充的开销。

同一簇内则适用标准的 Linux 调度器负载均衡——将负载均匀分散到簇内各核心;跨簇迁移则由 big.LITTLE MP 调度逻辑负责。

4.2 DVFS 感知的负载跟踪

跟踪负载并非简单的运行时间统计。它被设计为与 DVFS 频率变化协同工作:调度器会根据当前核心频率对负载进行归一化(frequency invariance),尽量消除频率变化对负载估计的影响。这避免了线程因核心降频而被错误地判定为”轻量”,使得 big.LITTLE MP 与 DVFS 能够协同工作。

4.3 Fork 迁移

当创建新的任务(如通过 fork()clone())时,没有历史负载数据可供参考。系统默认将新任务放置在 big 核心上,以降低高负载任务首次运行的响应延迟;如果后续判断其负载较低,再通过 Wake 迁移快速下迁至 LITTLE 核。

三类任务的行为差异:

  • 持续低强度任务(如 Android 系统服务):仅在创建时短暂运行在 big 核上,随后快速下迁至 LITTLE 核,几乎无额外开销。
  • 持续高强度任务:从 big 核启动,后续持续运行在 big 核——避免了”先在小核启动再迁移”的惩罚。
  • 间歇性高强度任务:从 big 核启动,大多数调度周期保持在 big 核上,利用 big 核的加速优势。

4.4 Wake 迁移

当任务从睡眠中被唤醒时,调度器需要选择将其放置在哪个簇上。核心机制依赖于跟踪负载的睡眠不变性:负载指标在睡眠期间冻结在最后一次运行时的值。因此,周期性繁忙的任务唤醒时总是倾向于分配在 big 核心上——只有任务真正改变其行为模式,在后续运行中以明显更低的计算强度执行,其跟踪负载才会逐步降低,最终触发下迁移。

  • 睡眠期间负载指标冻结在最后一次运行时的值
  • 周期性繁忙的任务(睡眠 → 唤醒 → 计算 → 睡眠)始终保持高负载指标
  • 这些任务唤醒时自然会被分配到与上次运行相同的簇——在 Fork 默认放 big 且高负载不触发下迁的前提下,相同簇通常为 big 核
  • 关键约束:上迁优先选择空闲的 big 核,以避免影响已经运行在大核上的高负载任务;下迁则不存在这一限制,可直接迁移至负载较低的 LITTLE 核
  • 只有任务真正改变其行为模式——长期减少计算量——其跟踪负载才会随时间衰减到触发下迁移阈值

主要说的是,睡眠期间跟踪负载不变,睡眠唤醒时用的是睡眠之前的值。

4.5 Forced 迁移

Fork 和 Wake 迁移都依赖”任务会偶尔睡眠”这一前提——在睡眠边界上产生调度点。但对于长期运行且从不睡眠的计算密集型任务,这两个机制无法生效。Forced 迁移通过定期检查来弥补这一盲区:调度器周期性地扫描每个 LITTLE 核心,如果发现任务跟踪负载超过上迁阈值,则将其迁移到空闲的 big 核心。这是一种主动的推(push)机制——由 LITTLE 核心端主动将过载任务推送至 big 核心,不依赖任务自身的睡眠行为。

4.6 Idle Pull 迁移

big 核心空闲时,Idle Pull 机制会主动搜索 LITTLE 核心上的高负载任务:检查所有 LITTLE 核心上是否有任务的负载超过上迁阈值——如果有,则将其迁移到空闲的 big 核心。如果没有找到合适的任务,big 核心则直接断电。这保证了 big 核心在活跃时始终承担系统中计算最密集的任务,big 核在空闲时则断电避免空转浪费能源。这种”大核作为加速器”的定位是 big.LITTLE MP 效能优势的关键来源。

4.7 Offload 迁移

GTS 默认不会像同构 SMP 那样进行跨簇负载均衡——这防止了轻量任务被分散到 big 核上。但副作用是:高负载任务会集中在 big 核,LITTLE 核可能空转而未被充分利用。Offload 迁移周期性地检查 big 核上的任务:将那些跟踪负载低于下迁移阈值的任务向下迁移到 LITTLE 核,利用 LITTLE 核的闲置算力。关键约束:下迁的任务仍然是上迁移的候选对象,如果下一次调度检查时负载回升超过上迁阈值,会被重新标记为上迁候选。

4.8 五种迁移机制协同全景

机制 触发源 方向 特点
Fork 迁移 新线程创建(fork() → big 默认上迁;轻量线程后续自然下迁
Wake 迁移 线程从睡眠中唤醒 保持或按负载迁 负载指标睡眠期间冻结
Forced 迁移 LITTLE 核周期性 tick 检查 LITTLE → big(推) 弥补无睡眠线程的盲区
Idle Pull 迁移 big 核空闲 LITTLE → big(拉) 大核即时空闲利用
Offload 迁移 周期性反向检查 big → LITTLE(推) 防止小核算力闲置

这五种机制覆盖了从线程创建、唤醒、长运行到核心空闲所有关键状态转换——形成一个完整的决策闭环。那么,这套机制在实际硅片上能带来多少能效收益?ARM 在真实平台上的测试数据给出了量化的答案。


5. 实践效果与软件生态

前面五章从硬件架构到调度器算法,完整呈现了 big.LITTLE MP 的工作链路。本章聚焦于它的实际交付——在真实工作负载下的功耗和性能数据,以及开发者如何获取并集成这套方案。

5.1 能耗与性能数据

ARM 在典型使用场景下测试了 big.LITTLE MP 相对于纯 Cortex-A15 系统的表现。比较对象是 四个 LITTLE 核心 + 四个大核心组成的 big.LITTLE 系统” vs 仅由四个大核心组成的系统

能耗表现

Benchmark

  • 线程数较多(>4)时:big.LITTLE MP 可以同时利用 big 和 LITTLE 核心,提高可用计算资源。
    • 当 big 核心繁忙时,Offload 迁移会将部分计算密集型任务分散到 LITTLE 核心。
    • 当 big 核心空闲时,Idle Pull 迁移会优先利用 big 核心作为性能加速器。
  • 线程数较少时:big.LITTLE MP 至少不会降低性能,通常还有小幅提升。原因是调度器可以让 big 核心专注运行高强度任务,避免被低负载系统服务或频繁中断干扰。

5.2 与 DVFS 和电源管理的集成

big.LITTLE 并非孤立技术。它与核心电源管理框架深度集成:

  • 核心断电:未使用的核心可以单独断电;若某簇中全部核心关闭,整个簇本身可以断电
  • DVFS 协同:DVFS 感知的负载跟踪确保 big.LITTLE MP 和 DVFS 和谐工作
  • PSCI 接口:通过电源状态协调接口(PSCI),迁移操作可以在多特权级 OS 之间协调进行

5.3 传统对称多处理的对比

维度 传统 4×big SMP 4×big + 4×LITTLE HMP
峰值性能 4 个大核 8 个核心同时上线的潜力
低负载功耗 4 个大核均需上电 仅 LITTLE 核活跃,big 核断电
后台任务干扰 后台服务占用大核算力 后台隔离在 LITTLE 核
热约束 大核长时间运行易触碰热墙 负载分流避免单个簇过热

6. 关键要点

以下九条要点从硬件基础、调度演进到电源管理,总结了 big.LITTLE 异构多处理的核心思想,可作为理解和评估异构架构的检查项。

  1. big.LITTLE 解决性能与能效的矛盾

    单一微架构难以同时满足移动设备”峰值性能 + 持续低功耗”的需求。big.LITTLE 通过组合高性能 big 核和高能效 LITTLE 核,在不同负载阶段选择合适的计算资源;HMP 进一步支持两类核心同时参与调度。

  2. 硬件 Cache 一致性是任务迁移的基础

    没有 CCI-400 等硬件一致性支持,big 和 LITTLE 核之间迁移任务需要频繁访问主存,导致延迟和功耗增加。硬件一致性使任务迁移对软件更加透明。

  3. 迁移机制是 DVFS 的扩展

    DVFS 通过调整频率改变计算能力,而 big.LITTLE 在此基础上增加了”切换核心类型”这一维度。当当前核心升频仍无法满足性能需求时,任务可以迁移到更强的核心。

  4. CPU Migration 比 Cluster Migration 更灵活

    Cluster Migration 以整个簇为单位切换,粒度较粗;CPU Migration(如 IKS)允许 big 和 LITTLE 核混合运行,提高资源利用率。但早期一对一绑定仍限制了扩展性。

  5. GTS/big.LITTLE MP 实现真正异构调度

    GTS 让调度器直接感知不同核心的计算能力,不再依赖固定 big-LITTLE 配对关系,使任意核心都可以参与任务调度,充分利用异构资源。

  6. 五种迁移机制覆盖线程生命周期

    • Fork:创建任务时选择核心
    • Wake:唤醒任务时重新评估
    • Forced Migration:运行过程中主动迁移
    • Idle Pull:空闲核心主动获取任务
    • Offload:高负载核心卸载任务

    五种机制共同形成动态负载均衡闭环。

  7. DVFS 感知负载跟踪避免调度误判

    频率变化会影响 CPU 实际计算能力,因此不能直接使用原始利用率判断负载。结合当前频率进行负载归一化,可以避免降频导致的负载低估。

  8. 睡眠期间冻结负载避免任务抖动

    对于音频、视频等周期性任务,睡眠期间保持已有负载状态,可以避免线程频繁迁移;只有任务行为真正变化时才重新触发调度。

  9. big.LITTLE 与电源管理深度结合

    异构调度不仅决定任务运行位置,也管理硬件资源状态。空闲核心和簇可以进入低功耗状态,并通过 PSCI 等接口协调 CPU 上下电和迁移。