【免费下载链接】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.
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 GHz | 144.1 | 82.2 |
| 进程级 background 钳制(E-core) | 0.74 GHz* | 12.0 | 8.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 个字段,缺一项即不予引用:
| # | 字段 |
|---|---|
| 1 | CPU 型号与微架构 |
| 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 条启示
- 比较数字前先问"哪个核":核心类型和主频是结果的"单位",就像 GB/s 本身只是单位。
- 提示不等于钉死:线程级
QOS_CLASS_BACKGROUND这次调度器根本没理会(仍留在 P-core),只有进程级钳制才真正换了核——所以必须记录工作实际跑在哪,而不是信任你的设置。 - 差距不能外推: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.
相关推荐
HandBrake性能基准测试:不同CPU/GPU的转码速度对比
HandBrake性能基准测试:不同CPU/GPU的转码速度对比 引言:为什么转码性能至关重要? 在当今视频内容爆炸的时代,无论是专业创作者还是普通用户,都面临
音视频视频处理桌面应用Synergy-core性能基准测试:不同硬件配置下的表现对比
Synergy core性能基准测试:不同硬件配置下的表现对比 Synergy core作为开源跨平台键盘鼠标共享工具的核心组件,在Windows、macOS和
桌面应用网络通信CANN/hcomm线程资源获取超时设置
HcommThreadResAcquireTimeOut 产品支持情况 Ascend 950PR/Ascend 950DT:支持 Atlas A3 训练系列产品
通信高性能计算人工智能CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考