ARM Cortex-A系列芯片性能对比:从A5到A78的DMIPS进化史
做嵌入式开发和芯片选型的人,几乎都绕不开一个问题:这颗ARM核心到底有多快?在过去的十多年里,大家衡量这个“快”字用得最多的一个指标就是DMIPS。从早期的Cortex-A5到如今遍地开花的Cortex-A78,单核DMIPS从每MHz 1.57一路爬升到接近9.5左右,翻了整整六倍。这背后不只是频率在涨,更是微架构设计思路的一次次推倒重来。
这篇文章我想以DMIPS为线索,把Cortex-A系列从A5到A78这条演进路线完整梳理一遍,聊聊每一代核心在设计上到底改了什么、为什么这样改、性能数字背后藏着哪些取舍,以及在真实项目里怎么用这些知识做选型。不管你是刚入门ARM Linux开发的新手,还是已经在用ARM Compiler做交叉编译的老手,这篇文章应该都能给你一些参考。顺便也会把我实测过程中踩过的坑、总结出的经验一并放进来,尽量让内容能直接落地。
1. 为什么都盯着DMIPS看:性能标尺是怎么来的
要谈ARM Cortex-A的性能进化,绕不开DMIPS这个单位。很多刚接触嵌入式开发的朋友看到数据手册上写着“1.9 DMIPS/MHz”或者“4.7 DMIPS/MHz”,第一反应是懵的——这个数到底代表什么?它又是怎么算出来的?
1.1 Dhrystone与DMIPS:一个古董基准的现代意义
DMIPS全称是Dhrystone Million Instructions Per Second,直译就是“每秒百万条Dhrystone指令”。它源自1984年Reinhold Weicker设计的Dhrystone基准测试程序,这是一套纯整数运算的测试,不涉及浮点、不涉及文件I/O、不做系统调用,纯粹考察CPU的整数处理能力。当时的参考机器是DEC的VAX 11/780,大家约定这台机器每秒能执行约1757次Dhrystone循环,把这个成绩定义为1 DMIPS。
所以DMIPS本身是个相对值,不是绝对的“每秒执行多少百万条指令”。它衡量的是被测CPU运行Dhrystone程序的成绩,相对于VAX 11/780的倍数。后来业界为了统一比较,又标准化出DMIPS/MHz这个指标,也就是“每MHz主频能获得多少DMIPS”,把频率变量消掉,纯粹看内核微架构的整数执行效率。这也是为什么芯片厂商喜欢拿它来宣传架构本身的优劣。
不过有话要说在前头:DMIPS这个诞生于上世纪80年代的测试程序,与现代真实负载的契合度并没有想象中那么高。它只测整数运算、代码量很小、可以完整放进L1缓存,所以对缓存系统、分支预测、内存访问延迟这类真实关键因素几乎“无感”。这就是为什么我们看DMIPS数据时,一定得搭配别的指标一起看,不能单独迷信它。但作为架构迭代的横向参考,DMIPS/MHz依然是目前使用最广、最直观的通用性能标尺,尤其是梳理历史演进时特别方便。
1.2 单核性能、频率与核心数的三角关系
理解DMIPS/MHz之后,下一个要认清的概念是系统总性能的计算方式。芯片厂商宣传“四核A73主频2.8GHz,性能X DMIPS”,这里的X通常是“单核DMIPS/MHz × 主频 × 核心数”,但这只是理论峰值。真实场景里因为缓存一致性、总线带宽、调度开销、功耗限制等问题,实际性能往往达不到这个数字。
举个很实际的例子:A53核心标称约2.3 DMIPS/MHz,一颗1.5GHz的四核A53,理论总性能是2.3 × 1500 × 4 = 13800 DMIPS,也就是13.8K DMIPS。但在实际跑多线程任务时,能跑到理论值的八成已经算优化得很不错了。原因很简单——四核共享的内存带宽和L2缓存会成为瓶颈,尤其是带宽敏感型任务。所以做选型时我习惯把理论值乘个0.7到0.85的系数,才能估算真实可用性能。
DMIPS/MHz的另一个价值在于,它不受主频影响,纯粹反映架构设计水平。比如A53能做到约2.3 DMIPS/MHz,A72能做到约4.7 DMIPS/MHz,两者的频率拉到同样的2GHz时,A72单核性能几乎是A53的两倍——尽管A53支持乱序的程度远低于A72,但差距就是实打实地摆在那里。理解了这层逻辑,后面我们看每一代核心的数字变化时,就明白它到底在讲什么故事了。
2. 从A5到A78,架构演进的三个时代
Cortex-A系列从2010年前后开始全面铺开,至今大概经历了三大阶段:第一是ARMv7时代的“小而美”与“高性能探索”并行的路线,第二是ARMv8时代64位化带来的性能重估,第三是A76之后“连续三年大幅挤出性能”的黄金期。每个阶段的侧重点和设计约束完全不同。
2.1 小而美时代:A5、A7与顺序执行的极限
Cortex-A5发布于2009年,是ARM为了替代Cortex-A8在低功耗市场的定位而推出的精简核心。它的设计目标非常明确:在最省电的前提下提供“够用”的性能,瞄准的是入门级智能手机、功能机、工业控制、物联网网关这类对功耗极其敏感的场景。
A5是顺序执行、单发射的微架构,8级流水线,没有复杂的乱序执行引擎,分支预测也非常简单。它的DMIPS/MHz数据大约是1.57,在主频普遍只有400MHz到800MHz的年代,单核性能大概在600到1200 DMIPS之间。这个数字在今天看来简直不值一提,但在当时的意义是:用极低的功耗成本完成基本的Linux运行、UI交互、网络协议处理。ARM官方当时宣传A5的面积只有A8的一半左右,功耗更是大幅降低,这让它成为很多MCU级产品向Linux级产品过渡的首选。
A7则是A5的全面进化版。同样定位低功耗、顺序执行,但它把流水线优化到8到10级,分支预测能力增强,并且引入了对ARMv7-A完整特性的支持,DMIPS/MHz提升到约1.9。更重要的是,A7被ARM官方定位成big.LITTLE架构中的“LITTLE”核心,和Cortex-A15搭配使用,在智能手机上实现了“轻负载用小核、重负载用大核”的调度策略。这个组合在2013年前后的智能手机市场非常经典,我记得当时很多主打续航的中端机用的就是A7+A15的混合架构。
从架构设计的角度看,A5和A7代表了顺序执行微架构的极限:再往下优化,就是A55那种更极致的效率取向;而再往上的性能空间,必须靠乱序执行来打开。这也是为什么A7之后,ARM没有继续在“小核心”路线上深挖单核性能,而是转去解决另一个问题——如何在小核心的能耗比基础上,获得接近大核心的性能。
2.2 乱序爆发时代:A9、A15、A17的性能探索
如果说A5、A7是“够用就好”的思路,那Cortex-A9就是ARM第一次认真挑战“高性能移动计算”的产物。A9发布于2007年,但真正大规模商用已经是2010到2012年之间的事。它是乱序执行、双发射的微架构,8级流水线,支持多核一致性,DMIPS/MHz约2.5。在那个主频1GHz到1.5GHz的年代,双核A9的芯片(比如瑞芯微RK3066、全志A31、TI OMAP4430)已经能提供相当流畅的网页浏览和游戏体验。
A9的重要意义在于它验证了“移动设备也能乱序执行”这件事。乱序执行允许CPU在指令依赖关系允许的范围内重新安排执行顺序,减少流水线气泡,从而提升单核吞吐量。代价是控制逻辑复杂度剧增、功耗和面积显著上升。在当时的工艺条件下,双核A9满载时的功耗已经让手机厂非常头疼,这也直接催生了后来A15的悲剧式电源管理需求。
Cortex-A15是真正的性能猛兽,也是功耗猛兽。它支持乱序、多发射、深度推测执行,DMIPS/MHz约3.5,四核A15跑到2GHz时理论总分可以达到28000 DMIPS以上,放在当时几乎是台式机级别的性能。但A15的功耗问题几乎是灾难性的:28nm工艺下四核A15满载功耗直逼5到8瓦,这在手机里是根本不可能长时间维持的。我记得当时很多用A15方案的平板,跑分惊人,但玩十分钟游戏后背板就开始发烫,然后系统强制降频,性能瞬间腰斩。这也是big.LITTLE架构被大规模采用的核心驱动力——不是A15不好,是手机散热扛不住,必须用小核来分摊日常负载。
A17作为A15的修正版,把功耗控制放在优先位置,DMIPS/MHz略高于A15但功耗大幅下降,不过它生命周期很短,很快被64位的A53/A57组合终结了。如果把A9到A17这段历史当作一个故事来看,核心线索就是:性能需求推动了乱序执行上移动端,但散热和电池技术没跟上,导致每一代高性能核都在功耗与性能之间痛苦挣扎。
2.3 64位与新世代:A53到A78的性能起飞
2014年,ARM正式推出ARMv8-A架构,指令集全面升级到64位,并同步发布了两颗定位截然不同的核心:Cortex-A53和Cortex-A57。A53是A7的64位继承者,继续走顺序执行、极致能效的路线,DMIPS/MHz约2.3;A57则是A15的正统接班人,乱序执行、性能取向,DMIPS/MHz约4.1。
A53的优秀程度在当时超出所有人预期。它的能效比极佳,面积小,四核A53在手机上跑日常应用的流畅度甚至不输双核A57。直到今天,A53架构仍然活跃在无数入门级SoC、路由器、智能电视、工业控制板上。我手头就有好几块基于四核A53的开发板,跑Linux系统、Python服务、轻量容器,几年下来非常稳定。A53的DMIPS/MHz虽然只比A7提升约20%,但得益于64位指令集和更现代的内存管理,实际综合体验提升远不止20%。
A57则是另一个故事。纸面性能非常强,但早期28nm和20nm工艺下功耗爆炸,手机厂商纷纷只敢用双核A57搭配四核A53,即便如此还是逃不过热降频的命运。后来ARM在A72上花了大量功夫把功耗优化回来,A72的DMIPS/MHz提升到约4.7,能效明显改善,成为骁龙650、660等中端神U的核心。A72的经验直接指导了后续A73的设计——不追求极限性能扩张,而是把每瓦性能放在第一位,结果A73在更低功耗下达到了接近A72的性能,DMIPS/MHz约5.5,成为一代神核。
真正的飞跃发生在A76。2018年发布的Cortex-A76把DMIPS/MHz一下子从A75的约5.5拉高到约7.2附近,IPC提升超过30%,同时功耗控制在合理范围。严格来说,A76是ARM时隔多年后第一次在整数性能上做出跨越式提升,背后是更宽的解码器、更大的乱序窗口、更强的分支预测和更深的重排序缓冲。紧接着A77和A78在A76基础上继续按每年15%到20%的幅度提升IPC,A78的DMIPS/MHz已经逼近9.5,配合5nm工艺可以轻松达到3GHz以上的主频,单核跑分直接追上低功耗x86处理器。
从A5到A78,这条进化线的本质是一场从“功能实现”到“效率艺术”的演进。前期的核心设计很像是在试探——到底怎么在功耗预算内堆性能?后期的A76、A77、A78更像是ARM已经把游戏规则摸透了,在同样的功耗预算里连续稳定地挤出每一丝指令级并行度。
3. 除了DMIPS,选型还必须看的几个指标
DMIPS/MHz可以看架构的代际差距,但到了具体选型环节,单看这个数据远远不够。我见过太多工程师被芯片厂商的宣传页带偏,拿到开发板实测才发现性能完全不是那么回事。所以这一节把我觉得必须补充的维度都聊一遍。
3.1 能效比:为什么A73赢了A72
如果把DMIPS/MHz代表“能力”,那能效比就是“用多少电换能力”。对绝大多数嵌入式项目和移动设备来说,能效比往往比绝对性能更关键。
A72和A73就是个绝佳案例。A72的DMIPS/MHz大约4.7,A73大约5.5,表面看A73只领先了17%左右。但A73的功耗大幅下降,同等性能下功耗可能只有A72的六到七成。这意味着在相同的散热条件下,A73可以达到更高的持续频率和更长的满载运行时间。换句话说,A73虽然单核纸面性能优势有限,但真实场景里“持续性能”反而更强,因为它的发热压力小,不容易触发降频。
这个道理放到今天依然成立。A78的能效比相比A77提升了大约20%,在同样的功耗预算下能跑更高频率,这正是它适合旗舰手机而不是塞进服务器机箱的原因。选型的时候我建议一定去查官方能效曲线图,而不是只看DMIPS峰值。如果厂商没提供,就自己用开发板跑一圈满载测试,用功率计测一测整板功耗,再算一下性能功耗比,这样得到的结论比任何宣传数据都靠谱。
3.2 缓存、访存与工具链:纸面数字之外的体验
DMIPS测试程序很小,能全部装进L1缓存里,所以它对缓存系统和内存带宽几乎不敏感。但真实应用完全不同。
拿几个典型的嵌入式场景举例:跑Qt界面应用时,图像资源、字体渲染、布局计算都需要大量访存,这时候L2缓存大小和内存带宽的影响远远大于DMIPS数字本身——这也是为什么同样的A55核心,在一些SoC上跑Qt流畅,在另一些SoC上卡成幻灯片,差异很大程度来自内存子系统。跑视频编解码时,硬件编解码器占主导,CPU的DMIPS意义变小;跑WebRTC、FFmpeg这类重度整数计算时,DMIPS的参考价值才明显。跑AI推理时,NPU和DSP才是主角,CPU的DMIPS几乎可以忽略。
工具链对实测成绩的影响同样巨大。同一颗A55核心,用老的ARM Compiler 5默认优化等级编译Dhrystone,和用ARM Compiler 6或者GCC搭配-O3 -march=armv8-a+crc编译,跑出来的DMIPS可以差20%到30%。我甚至见过有人用不同编译器跑的分数跨代对比,得出了完全错误的结论。所以做性能对比时,一定要确保编译工具链、优化选项、运行条件一致,否则就是拿苹果比橙子。
3.3 如何用跑分实测一颗ARM芯片的DMIPS
理论说再多,不如自己动手跑一遍。这一节给出一个我在实际项目里验证过多次的参考流程。
第一步,准备环境。在目标板上装好Linux系统,确认CPU核心数和最高频率。如果没有Linux,也可以使用裸机环境配合ARM Compiler工具链编译测试程序。建议先把CPU频率锁定,避免频率跳动导致数据忽高忽低。在Linux下可以用cpupower frequency-set -g performance把调频策略设为performance模式,同时关掉其他负载。
第二步,获取Dhrystone源码。经典的Dhrystone 2.1源码在老版本的linux/tools/perf/bench/dhrystone.c里可以找到,也可以从各种开源仓库单独下载。代码不大,几百行,结构非常简单,基本不需要移植。
第三步,编译。用你的交叉编译工具链编译,注意优化选项。我自己常用的命令大概是:
arm-linux-gnueabihf-gcc -O3 -march=armv7-a -o dhrystone dhrystone_2.1.c编译选项里的-march一定要根据目标架构调整,A53用armv8-a,A72用armv8-a,老旧的A9内核就用armv7-a。如果工具链支持,加上-funroll-loops也能对跑分产生明显影响,但这个选项未必反映真实应用性能,所以正式评估时我不建议加。
第四步,运行并记录结果。程序运行结束会打印出每秒迭代次数,把迭代次数除以频率,再换算成DMIPS/MHz。例如每秒跑2000000次迭代,换算大约是1145 DMIPS,在主频1GHz的A53上就是约2.29 DMIPS/MHz,基本对得上官方标称值。
第五步,多跑几次取平均值。个别核心存在变频、偷停、调度干扰等问题,单次测试波动可能达到5%以上,至少跑三次取中位数比较稳妥。如果条件允许,建议同时用perf stat采集IPC数据,这比只看DMIPS更能看出架构效率差异。
4. 从跑分到产品:性能数字怎么落地
数据手册上的DMIPS只是参考,真正落地到产品选型时,要考虑的维度包括场景匹配、SoC周边配置、软件生态、成本功耗等等。这一节结合我实际做过的一些项目,聊聊怎么把DMIPS知识用到决策里。
4.1 消费级SoC的典型组合与调度
以手机和平板为代表的消费级产品,近几年几乎清一色采用ARM的big.LITTLE或DynamIQ架构——高效小核+高性能大核的混合组合。典型的组合有:
- A53 + A57/A72:2015到2017年中端主流,小核负责待机、推送、音乐后台;大核负责网页渲染、游戏、照片处理
- A55 + A76/A77/A78:2019年后的主流组合。A55小核能效比优秀,A76以上大核提供旗舰性能
- 全大核的A78方案:部分主打性能的设备干脆不用小核,全用A78,比如一些高性能平板和游戏手机
这种组合的调度策略对体验的影响不亚于芯片本身的性能。很多Linux系统和Android系统的调度器在大小核之间来回切换,如果迁移延迟过大,用户感知就是“卡一下”。我调试过一些基于A55+A76方案的板子,为了优化后台任务调度,需要手动调整cpufreq的governor策略,甚至绑核运行特定进程,才能让应用流畅度和功耗达到可接受的水平。
在做这类SoC软件开发时,建议在系统启动脚本里根据应用场景预设CPU调频策略:交互式应用把大核的scaling_min_freq调高一些,后台服务则绑到小核上运行。这些细节对性能调度非常关键,单纯追求理论DMIPS没有任何意义。
4.2 嵌入式开发中的实际选型参考
在工业控制、边缘计算、智能终端设备这类嵌入式场景里,我的选型思路一般遵循几步走。
先明确任务负载类型。如果产品以网络协议处理为主,比如路由器、网关,那多核A53/A55方案就够用,因为这类任务并行度高、单核性能要求不高,更看重多核吞吐和网络硬件加速能力。如果产品要跑本地推理、图像处理这类计算密集任务,优先选择带NPU或者GPU加速的SoC,同时CPU端至少A76以上,否则前处理和后处理容易成为瓶颈。如果产品要跑复杂的Qt用户界面,单核性能比核心数更重要,A72单核四核可能比A53八核更流畅,因为UI事件响应和绘制线程很大程度上依赖单核性能。
再确认工具链和软件生态。比如你要跑特定版本的Linux发行版或者某个预编译的软件包,就得先确认目标架构是armv7还是armv8,是硬浮点还是软浮点ABI。很多工业项目中用的是老旧的ARM Compiler 5工具链,那对CPU架构的支持就有上限,容易在较新的A76/A78上产生兼容性问题。如果必须用老工具链,选型时优先挑那些ARMV7-A时代兼容性比较好的核心,比如A9、A15、A7,而不是最新一代的A78。
最后给个实际例子。我之前做一个边缘视频接入网关,初始方案选了全志的A53四核方案,跑FFmpeg转码时CPU占用率持续保持90%以上,整板功耗4到5瓦,有时还会触发热保护导致转码中断——主要原因就是A53顺序执行的架构在FFmpeg这类重度整数负载下效率偏低。后来把方案换成RK3568这颗A55四核代际更新的芯片,同样的任务CPU占用率降到60%左右,转码帧率从13fps提升到21fps,整板功耗反而降了约一瓦。从这个案例能直观看到,即使DMIPS/MHz只是从2.3提升到2.7,对重度计算任务的实际帮助也非常可观。
5. 常见误区与排查实战
做性能评估和开发调试的过程中,我总结了不少容易踩的坑。这里整理出来,算是给大家当个避雷指南。
5.1 DMIPS认知的四个坑
第一坑:拿DMIPS当唯一性能标准。DMIPS只测整数运算,不涉及浮点、内存、I/O、缓存、分支预测压力等真实负载要素。一个DMIPS/MHz偏低的核,如果浮点单元和缓存系统做得好,实际体验可能反超。所以一定要搭配SPECint、CoreMark、Geekbench这些更全面的基准一起参考。
第二坑:把DMIPS看成可相加的量。四核芯片的总DMIPS并不是简单乘以四。受制于总线带宽、缓存一致性和调度开销,多核扩展效率普遍达不到线性。跑并行任务前,先跑一个简单的多线程压力测试,看看实际扩展率是多少会更靠谱。
第三坑:忽略频率变化和DVFS影响。芯片标称“最高2.0GHz”,实际上大部分时间运行在1.2GHz,这时候按2.0GHz算出来的DMIPS毫无意义。评估真实性能一定要看“持续工作频率”,也就是满载运行一段时间后热稳定下来的频率,这个频率在手机SoC上往往只有标称最高频率的七成水平。
第四坑:不同代际之间横向比较时忽略测试条件。编译选项、运行环境、外设状态、温度,都会影响数值。之前有人拿一颗老ARM核心在裸机上用armcc跑出的高分,和一颗新核心在Linux里用GCC跑出的低分做对比,得出“老架构比新架构还强”的荒谬结论,这种错误在论坛里真不少见。
5.2 实测中的工具链与编译问题
跑基准或调优时,最常碰到的工具链问题主要集中在几个方面。
ARM Compiler 5和ARM Compiler 6是两个完全不同的编译器体系。AC5(armcc)是传统Arm Compiler,编译选项和GCC完全不同,代码生成效率在老旧架构上表现不错,但到了A76/A78这种新架构上,默认选项生成的代码往往发挥不出新架构的优势。AC6(armclang)基于LLVM,更契合新架构的优化需求。所以如果你还在用AC5跑新内核,建议切换到AC6或者GCC重新对比一下,性能差距可能非常明显。ARM官方从2020年起已经宣布AC5停止更新,长远来看迁移到AC6是不可避免的趋势。
GCC交叉编译时,优化选项影响巨大。-O2和-O3的差距在嵌入式场景经常是10%到20%的浮点或整数性能差异。更关键的是一些特定架构优化标志,比如-mtune=cortex-a72会在A72上针对性地调整指令调度,但同样的二进制放到A55上跑就可能表现一般。所以发布给不同SoC使用的软件,建议针对目标架构做单独编译,不要图省事用同一份二进制通吃。
Keil MDK环境下的ARM Compiler配置也常出问题。MDK 5默认只安装AC6,有时候你打开以前的老工程,里面编译脚本还写着armcc的调用方式,就会报*** error: createprocess failed之类的错误。解决办法是在MDK的Pack Installer里重新勾选安装ARM Compiler 5,或者把工程迁移到AC6的armclang命令。对于老产品维护,我建议保留AC5环境,因为老工程的启动代码和分散加载文件未必能直接通过AC6编译。
5.3 踩坑速查表
| 症状 | 可能原因 | 排查思路 |
|---|---|---|
| 跑分远低于标称值 | 未锁定频率、DVFS生效 | 用cpupower锁定performance模式,确保温度不触发降频 |
| 多核跑分扩展率很低 | 内存带宽瓶颈、调度不均衡 | 查看perf stat的IPC和缓存未命中率,尝试线程绑核 |
| 同样代码不同板上性能差异大 | 编译器版本、优化选项不一致 | 统一工具链版本、统一-march/-O选项 |
| Dhrystone闪退或报错 | ABI不匹配、硬浮点库缺失 | 检查工具链是gnueabihf还是gnueabi,确认内核支持VFP |
| 新核心跑旧系统卡顿 | 内核太老、缺少新架构优化 | 升级内核,检查设备树对CPU特性的描述是否完整 |
最后分享几个我在实际使用中的小技巧。评估芯片性能时,不要只跑Dhrystone,建议同时跑一下CoreMark和简单的内存带宽测试(比如lmbench的bw_mem),三个维度合起来才能对芯片能力形成立体认识。做产品选型时,选一颗好芯片远不如选一套成熟SDK重要——同样的A53核心,不同厂商的BSP质量差别非常大,糟糕的电源管理会让A53跑出A7的效率。交差编译环境一定要统一,团队里大家都用同一个Docker镜像编译,否则不同人拉出来的库版本不一样,最后联调时全是问题。我自己曾经因为开发机人编译器GCC版本差异导致一个C++库的ABI不兼容,在目标板上调试了整整两天才定位到根因,从那以后强制全团队统一编译环境。