☰
CPU Performance Engineering 指南:P-core 与 E-core 同码不同速(12 倍差距)——基准可比性的前提
2026/10/15 18:12:06 网站建设 项目流程

【免费下载链接】cpu-performance-engineering

A reading path for CPU performance engineering, from one instruction to production inference. Primary sources only, with a runnable benchmark for every section.

项目地址:https://gitcode.com/gh_mirrors/cp/cpu-performance-engineering
点击查看免费下载

CPU Performance Engineering(cpu-performance-engineering 开源项目)是一条面向 CPU 性能工程的完整学习路径:从单条指令一路到生产级推理,每一节都配一个可复现、可直接运行的基准测试。本文聚焦其中第 14 号实验:在混用 P-core(性能核)与 E-core(能效核)的异构芯片上,同一份代码两种核心的速度差最高达 12 倍——而这正是"两个基准数字能否比较"这一前提问题的核心。

一、CPU 性能工程中的 P-core 与 E-core:异构 CPU 基础

现代 CPU 性能工程不能再假设"芯片上的核都一个速度"。异构芯片混装两种核心:

  • P-core(performance core,性能核):管线宽、主频高、缓存大,负责交互式、低延迟任务
  • E-core(efficiency core,能效核):管线窄、功耗低、缓存小,负责同步、索引等后台任务

调度器决定每个线程落在哪种核上。同一份二进制,两种核心可以差出数倍——你无法默认代码跑在"标准核"上。

实验机为Apple M4 Pro:10 个 P-core + 4 个 E-core,无 SMT,机器完整描述见 misc/benchmarks/README.md#L26-L37。

二、实验设计:同一份代码、三种瓶颈、四种放置

14-pcore-vs-ecore 实验把 3 个覆盖 CPU 性能工程三大瓶颈类型的微基准,跑在 4 种线程放置方式上:

微基准度量瓶颈类型
dep_add_chain(依赖加法链)有效主频(每周期 1 次加法)CPU 时钟
fma_l1(16 累加器 NEON FMA)向量计算吞吐 GFLOP/s计算管线宽度
stream_sum(64 MiB 流式求和)流式读取 GB/s带宽与访存并行度

四种放置(源码 bench.c):① 主线程默认启动;② pthread 不设 QoS;③ pthread 请求QOS_CLASS_BACKGROUND(通常认为的"E-core 提示");④ 整个进程用taskpolicy -c background钳制到后台类。

⚠️关键设计:macOS 不向用户态开放 CPU 亲和性 API,实验没有"钉死"任何线程,而是让每个采样都记录线程起止时实际所在的 cpu id,以及线程真实的 CPU 时间占比——看调度器到底把活放到了哪,而不是信任提示。

三、实测 12 倍差距:P-core 与 E-core 性能对比结果

调度器实际只把第 ④ 种放到了 E-core(cpu id 0-3),前三种都留在了 P-core。结果摘录(数据源 results/summary.md#L10-L15):

放置方式(实际核心)时钟(中位)FMA GFLOP/s流式 GB/s
主线程默认(P-core)4.50 GHz144.182.2
进程级 background 钳制(E-core)0.74 GHz*12.08.4

* 墙钟口径;E-core 与系统后台任务共享,线程实际只获得 75.8% 时间,按线程 CPU 时间口径中位主频为 1.12 GHz。

差距不是一个数,而随瓶颈类型变化(P-core / E-core 比值):

口径时钟计算 FMA内存流式
墙钟6.12×12.01×9.82×
线程 CPU 时间4.03×9.01×7.52×

同一台机器、同一份代码,三个微基准给出三种不同的差距因子。

四、差距拆解:时钟 × 管线宽度 × 带宽

为什么计算差距(12×)远大于时钟差距(约 4-6×)?按每周期口径看:P-core 维持4.00 FMA/cycle(4 条向量管线喂满),E-core 只有1.97(管线宽度约一半):

计算差距 ≈ 时钟差距 × 管线宽度差距(4.03 × 4.00/1.97 ≈ 8.2,实测 9.01)

内存流式同理:E-core 每周期搬 10.6 字节,P-core 是 18.2——流式差距比时钟差距还大。因为单条读流受限于单核能同时保持多少个未命中请求(访存并行度)和预取器能提前多远,这两样 E-core 都更少。

另一个发现:E-core 也不是单一速度——同一次运行中主频在 1.52 GHz(最快采样)到 1.12 GHz(中位)之间漂移,变异系数 9.8%,钳制后的簇频率被"那里还跑着什么"带着走。

五、基准可比性的前提:每个数字必备的 7 个字段

本项目的核心主张(也是 CPU 性能工程的基本纪律):一个不说清核心类型和主频的基准结果,是"没有单位的数字",不能与另一个结果比较。

项目 README.md#L690-L705 定义了每个数字必须携带的 7 个字段,缺一项即不予引用:

#字段
1CPU 型号与微架构
2使用的核心数
3主频(含 turbo 与 SMT 状态)
4编译器与编译参数
5工作负载
6基线
7测量方法

完整原始数据(机器描述、负载、每个采样的 cpu id)见 results/raw.txt。

六、如何在自己机器上复现 P-core E-core 基准测试

源码为 C11 + pthreads,带#if守卫可同时在 Linux x86-64 / arm64 编译(非 Apple 平台跳过钳制放置,可用taskset/cpuset 代替)。若本地尚无仓库:git clone https://gitcode.com/gh_mirrors/cp/cpu-performance-engineering

cd misc/benchmarks/14-pcore-vs-ecore ./run.sh # 完整运行,约 10 秒 QUICK=1 ./run.sh # 冒烟测试,约 2 秒

run.sh 会先在输出顶部写入机器描述与负载均值,再用 common/clock_estimate.c 的依赖加法链估算主频(本机:P-core 约 4.49 GHz,background 钳制下约 1.04 GHz)。

七、给新手的 3 条启示

  1. 比较数字前先问"哪个核":核心类型和主频是结果的"单位",就像 GB/s 本身只是单位。
  2. 提示不等于钉死:线程级QOS_CLASS_BACKGROUND这次调度器根本没理会(仍留在 P-core),只有进程级钳制才真正换了核——所以必须记录工作实际跑在哪,而不是信任你的设置。
  3. 差距不能外推:12× 的计算差距与约 8-10× 的内存差距来自同一台机器的不同瓶颈;把 P/E 核差距当成一个固定倍率,会高估或低估你的每一项优化。

项目其余 13 个基准覆盖分支误预测、缓存延迟、测量陷阱、伪共享、NUMA first-touch、协同遗漏等主题,完整清单见 misc/benchmarks/README.md。

【免费下载链接】cpu-performance-engineering

A reading path for CPU performance engineering, from one instruction to production inference. Primary sources only, with a runnable benchmark for every section.

项目地址:https://gitcode.com/gh_mirrors/cp/cpu-performance-engineering
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询