氪金一时爽,一直氪金一直爽
在对M1评价的那个回答里面,我没有具体评价M1的CPU部分,一方面是苹果公开的资料极少,另一方面也是当时产品未开卖,具体性能表现不明,所以只是针对整个SoC进行了评论。就在这个问题下补充一下对M1 CPU部分的评价吧。
创作声明:写苹果M1的CPU分析是痛并快乐着。作为硬件爱好者看到一个性能这么强的CPU总是忍不住去关注想去深入了解,但苹果不公开技术细节的尿性又让我只能到处找一些其它资料来管中窥豹。本文会有大量的间接推测结论,我无法对其正确性负责。
IPC王者
我写这个答案的现在,相信很多朋友都看到过M1的各种评测了,如果说M1是单核之王可能AMD Zen3的5950X不服,但说是IPC之王应该毫无争议了。仅仅工作在3.2 GHz的M1,和最高睿频4.9 GHz的5950X打的有来有往。至于多线程性能,受限于只有四个FireStorm的高性能核心,肯定不如16核的5950X,但和只有6核的Zen3 5600X,8核的i9-9980HK比,却是不落下风。(别忘了,搭载M1的Mac Mini,整机满载也就30W出头,而5600X是桌面CPU,9980HK是45W TDP还往往轻松跑出80W+的功耗,这两个CPU还都支持超线程的。)
这里简单贴一下Anandtech评测搭载M1的Mac Mini的几个结果[1]:
CineBench R23单线程
CineBench R23多线程
GeekBench 5单线程
Geekbench 5多线程
功耗
Anandtech的原文后面还有SPEC2006、SPEC2017的评测,图比较多我就不贴了。而且A站统一用Clang编译SPEC的方式,时不时就有人说用ICC编译成绩可以更强之类的,这里就不提了。
另外,Geekbench官网提供了大量用户上传的测试成绩来方便比较,有兴趣的朋友,可以拿不同的CPU来和M1进行对比,看看M1强在什么地方。例如我就随便贴一个M1的MBP13和i9的MBP16的对比链接:
ARM的胜利?
其实,M1是苹果自研的A系列SoC中最新的A14的变种,自从苹果第一款支持ARMv8指令集的A8开始,A系列的IPC、单核性能一直很强,吊打一众安卓SoC,多次在一些跨平台的评测软件中跑出和x86相近的得分,GeekBench更是因此一直被戏称为AppleBench。
在M1之前,A系列仅用于苹果自家的移动设备:iPhone和iPad,独有的操作系统,移动设备有限的功耗,使得A系列和其它CPU,尤其是主要用于笔记本、台式机的x86 CPU的性能对比结果一直难以回避“软件平台不同”的质疑。即便是相对来说业界比较认可的SPEC评测,也因为需要自行编译,运行结果会因为操作系统、编译器、编译参数不同而有所偏差。所以这些年来,很多人逐渐接受“苹果的A系列很强”这个结论,但“到底有多强,能不能比x86强”则一直没有一个获得普遍认可的结论。
这次的M1,应用在苹果自家的Macbook、Mac Mini上,功耗限制放宽了不少,同样基于苹果的macOS,第一次正面挑战x86,苹果交出了一份让大家满意甚至惊讶的成绩。
M1:高成本换来的高性能
苹果目前并没有公开太多M1的细节,Anandtech使用Veedrac的架构测试软件[2],根据测试结果,推测的架构图如下(仅供参考):
192 KB的L1I(Leve 1 Instruction Cache,一级指令缓存),8路解码,630条目的ROB(ReOrder Buffer,指令重排缓冲区),6个ALU(Arithmetic Logic Unit,算术逻辑单元),两个乘法单元,一个除法单元,两个分支控制单元,4个内存读写单元(其中一个可以进行读写操作,一个写入操作,两个读取操作),4个128bit浮点/SIMD单元。此外,还有约354个条目的整数寄存器文件,384个条目的浮点寄存器文件,128 KB的L1D(Leve 1 Data Cache,一级数据缓存)。
作为对比,这里列一个x86最近几款CPU核心架构的参数:
可以看到,最重要的执行单元部分,M1/A14的6个ALU,4个FPU带来的最高理论性能直接就比其它CPU高50%~100%(暂不考虑x86 256bit的AVX)。而M1的L1/L2容量、解码宽度、ROB规模都非常大,往往是其它CPU的两三倍(其中12 MiB的L2容量是四个大核共享,平均3 MiB/核心,但运行单线程应用的时候,理论上可以全部由单个核心使用),前端、调度单元、缓存的庞大规模,保证了执行单元能最高效率发挥性能。
所以,不考虑更多细节的话,假设大家性能效率发挥基本一致,理论上M1的IPC,整数方面应该比Zen2/3、SKL、SNC都高50%;不考虑AVX,浮点方面比Zen2/3、SKL/SNC高100%。而x86的高频率所必须的长流水线,在分支预测失败需要重新填充流水线的时候,惩罚会比M1高,所以实际IPC要更低些;Intel家的FPU和ALU共享发射端口,IPC估计会更低一点。
可能会有人问,既然宽架构的性能这么强,为什么别的CPU厂家不做呢?答案很简单:成本。上面这些规模庞大的单元,每一个都要比其它CPU多消耗不少的晶体管。在这里做一个不靠谱的估算:
已知条件:M1总晶体管规模160亿,Anandtech放出来的下面这张高清Die Shot分辨率1180×1125,单个Firestorm内核大约150×168像素。
假设整个M1的晶体管密度基本均匀,可以推算出,不含L2的单个内核,使用了接近3亿晶体管。
作为对比,AMD的Zen2,单个CPU核心(含L2+L3Cache,共4.5 MiB)的晶体管规模大约是4.75亿,面积7.83 mm²,不含L3的面积是3.64 mm²,算下来核心部分大约使用了2.2亿晶体管。Firestorm消耗的晶体管大概比Zen2单个核心(含L2不含L3)多了38%。
而且其中比较消耗晶体管的SIMD单元,Zen2是256 bit×2,Firestorm是128 bit×4,可以假设:
M1和Zen2的SIMD单元消耗的晶体管数量相近Zen2的浮点单元占比和同样支持256 bit×2 SIMD的Intel SandyBridge相近,75%(从Intel提供的CPU内核功耗分布推算[3])
M1除SIMD单元外的其它部分,消耗的晶体管数量为Zen2的250%。即便把Zen2的SIMD占比降低到50%,其它部分M1消耗的晶体管也是Zen2的175%。M1这个超宽架构,消耗的晶体管大概是Zen2的两倍左右,几乎可以直接用来做两个Zen2性能级别的核心。PS:i9就不说了,不管是14nm工艺,还是Skylake内核,都是五六年前的东西,对于日新月异,一两年一换代的半导体行业来说,现在还能被人拿出来鞭尸,鞭的时候还能动弹一下,已经足以说明Intel的强大了——只是要加个前缀,“当年”。
对于苹果来说,想要获得高性能,这个晶体管成本是必须付出的。用于移动设备的A系列因为电池技术、散热方式、续航时间的要求,功耗有限,无法让CPU工作在高频率下,只能用晶体管数量来换取高IPC来获得高性能,由A14派生出来的M1自然也只有这个选择。好在以苹果的产品价格和利润率,还是足以覆盖这个成本的。移动设备用户需要处理的数据量有限,iOS/iPad OS的杀后台机制也保证了需要的内核数量有限。常见的几种需要处理大量数据的应用所需要的高性能,则是由SoC上的专用处理单元如GPU、NPU、视频编解码单元、图像处理单元、加密解密单元等来提供。
然而对于主要面向笔记本平台、桌面平台、服务器平台的x86来说,只要频率提高到4.8 GHz左右就能获得同样的性能——而这些平台的功耗要求并不算严格,即便是只有15W的低压笔记本平台,通过睿频技术也足以允许1~2个核心运行到4 GHz以上,那么就变成了另一道选择题:到底是用200%的晶体管来实现150%的单线程性能?还是保持单线程没有变化,用200%的晶体管来实现200%的多线程性能?
不同于苹果,x86的用户,下有大量成本敏感的低端用户,他们对CPU的性能要求是够用就行,不会接受过于高昂的CPU售价;上有大量的企业级用户,各种各样的应用和算法对CPU性能的要求多种多样,无法用有限的专用单元来满足,只能由CPU来提供——如果企业没有GPU开发能力,或者需要的算法在高性能但相对不灵活的GPU上效率很低的话。
对于这些企业应用来说,同等规模的晶体管多实现几个核心,不见得比架构宽但核心少的CPU差。上面Anandtech的测试中,15W的4800U的Cinebench成绩,单线程即便频率比M1高了近30%性能还落后20%,但凭着8核心+SMT,已经超过了四大核+四小核的M1。即便在苹果相当占优的Geekbench中,部分散热好的机型也能获得超过M1的多线程成绩。
CISC的困境
即便x86厂商不在乎成本,想做一个类似的超宽架构旗舰来和M1对标,那就要面对CISC指令集的一个缺陷了:变长指令造成的解码性能限制。
采用x86指令集的PC属于CISC(Complex Instruction Set Computer,复杂指令集计算机),上世纪70年代末业界提出了RISC(Reduced Instruction Set Computer,精简指令集计算机)的概念并为一众高性能服务器厂商所实现,如IBM的POWER、DEC的Alpha、Sun的SPARC等。RISC的理念是CISC中,20%的常用指令占了80%的比例,因此只需要保留这20%的简单指令即可。和CISC相比,RISC没有内存操作数,指令定长,早期的RISC指令数量少。因此RISC CPU的解码、执行电路实现简单,指令执行速度快可以工作在更高频率。但RISC也有其缺点,例如CISC中的某些指令在RISC中需要使用多条指令实现来实现相同的功能,定长指令浪费内存空间,对内存带宽压力更大等。
此后的时间内,CISC和RISC之争就没真正平息过。90年代中期Intel推出了P6架构的奔腾Pro,内部做了一个把CISC的x86指令转换、分拆为类似RISC的内部μOPs(Micro Operations,微操作),对简单的指令使用硬件电路直接解码,对常用的复杂指令使用复杂解码器解码,对不常用复杂的指令使用微码序列器进行分解(题外话:微码序列器是现代x86 CPU可以采用微码修复硬件bug的根基)。P6之后的x86凭着这个机制实现了和RISC相近的性能,也是进入新世纪后x86打垮一众RISC服务器的基础。此外,随着半导体工艺提升,CPU频率突破3 GHz后因为功耗问题频率提升困难,RISC也不得不加入更多的新指令来提升性能,CISC和RISC的差异也越来越少。
但即便到了今天,x86的变长指令一直是实现高性能解码器的噩梦:解码器需要解析完一条指令得知本条指令长度后,才能计算出下一条指令的起始地址;在此之前,CPU无法知道下一条指令从哪里开始,对连续的指令序列无法分拆后并行解码。虽然程序中会有类似跳转(JMP)、调用(CALL)这样的分支指令,其操作数是某条指令的起始地址,另一个解码器可以从该地址开始解码,实现对指令序列进行并行解码。但毕竟程序中这样的指令密度有限,即便CPU中有更多的解码器对更多分支的指令并行解码,往往某个解码器解码后的μOPs在多个时钟周期内也不会进入执行序列。今天的x86 CPU,AMD已经是四个复杂解码器,Intel是一个复杂解码器+四个简单解码器,已经有点过于富裕,这也是两家的CPU都支持SMT(Simultaneous MultiThreading,同时多线程,也就是Intel的Hyper Thrading,超线程),并且开启SMT后多线程性能往往有相当幅度提升的一个重要原因,因为对两个线程并行解码后可以进入执行序列的μOPs数量更多。
而RISC的定长指令,指令抓取单元直接对指令序列按长度分割后,交由不同的解码器并行解码即可。因此我们可以看到两个超宽的RISC架构:IBM最新的POWER可以配置为支持SMT8,以及虽然不支持SMT但IPC惊人的苹果A系列。在CISC的x86上则没有出现过类似的超宽架构。
最后总结:M1的CPU,是在:1、成本不敏感;2、使用最先进的半导体工艺;3、目标用户群体需求有限的前提下,获得的当前最优秀的功耗-性能平衡点。而没有这些前提的x86,则是面对复杂得多的应用环境,以多线程性能为目标达到的另一个成本-功耗-整体性能平衡点。参考^Anandtech:The 2020 Mac Mini Unleashed: Putting Apple Silicon M1 To The Testhttps://www.anandtech.com/print/16252/mac-mini-apple-m1-tested^Github:Veedrac/microarchitecturometerhttps://github.com/Veedrac/microarchitecturometer^[PDF]Race to Exascale: Opportunities and Challengeshttps://www.microarch.org/micro44/files/Micro%20Keynote%20Final%20-%20Avinash%20Sodani.pdf