【转】Apple M1 Icestorm微架构评测:重铸小核荣光(架构分析)
Apple M1 Icestorm微架构评测(上):重铸小核荣光

JamesAslan喜欢画画和摄影的硅工码农(滑稽)Luv Letter 等

前言
M1的横空出世可谓彻底改变了消费级市场的格局,凭借极高的性能和极低的功耗,Apple sillion在手机之外的移动端开疆扩土。抛开生态问题,同期生AMD Zen3和Intel Sunnycove与之相比简直乏善可陈,Arm公版更是相形见绌;究其根本,M1这股新风仿佛让我们看到了海的彼岸,让身陷x86频率竞赛的世界看到另一种可能。 M1大核微架构Firestorm堪称苹果大核心宽发射路线的集大成之作,让Arm架构无法胜任高性能的说法不攻自破,将体系结构Brainiac与Speed Demon的世纪之争带入了崭新的维度。在Firestorm的光芒下小核Icestorm往往为人所忽视,然而Icestorm对M1的成功不可或缺;与羸弱的A55、A510不同,其能够很好地胜任系统任务、后台任务,提供良好体验的同时保持极低的功耗。我们这次就来探究Icestorm的微架构。
基准测试
在这一部分我们使用SPEC06、SPEC17、Coremark以及Verilator对处理器进行测试。注意,我们并不执着于fine-tune以获得某一微架构的最高分数;而是以合理、统一的编译参数带来可比的分值数据。SPEC06、SPEC17等的分值受系统环境、编译器版本、编译参数、BIOS调教、频率稳定性、具体SKU的Cache配置、具体平台的内存参数等因素影响巨大,且无法通过任何简单线性缩放进行分数推演。
频率
我们使用的平台是Apple Mac mini M1;处理器为Apple M1。在Arch Linux下其小核icestorm稳定运行频率为2.05GHz,以下的测试都基于2.05GHz的频率进行。
SPEC06
SPEC06是已经退役的SPEC测试集但是仍然被广泛使用;其负载特性与SPEC17并不相同,因此仍然具有相当的测试价值。

我们选取了A76、A78这两款处理器作为参考对象,因为互联网上常有A76与Icestorm孰强孰弱的讨论。在绝对性能上Icestorm全面落后于A76、A78,但是从IPC上来看Icestorm强于A76弱于A78。由于苹果目前特殊的核心簇互联设计,Icestrom先天受制于E核簇较小的可访问L2 Cache规模,在部分子项上无法发挥全部实力。但是从462、429子项来看,Icestorm配备了相当强悍的数据预取器,一定程度上弥补了Cache子系统容量的不足。从400子项上来看,Icestorm的间接跳转预测器还有较大的进步空间,主预测器容量也遇到了瓶颈,0.91%的分支误预测率高于当代所有Arm、X86竞品。出于定位考量Icestorm相对不擅长浮点,IPC与A76相近。当然这里的对比有些越级的意味,从自身定位角度看Icestrom的成绩可圈可点。
SPEC17
SPEC17是现役的SPEC测试集,被广泛用于微结构性能评估。

SPEC17测试中,三款处理器的相对结论并没有变化,只是Icestorm相对A76不再具有综合IPC优势。实际上SPEC17测试集相对SPEC06测试集对数据预取的敏感度更低,换言之Icestorm较小的L2 Cache容量会成为更加明显的瓶颈。此处也不得不称赞ARM Cortex A系列的演进,A78相较A76的提升十分全面,在几乎所有子项上都有正向提升而非“取舍的艺术”。
Coremark
Coremark是一款嵌入式基准测试程序,其受下级Cache子系统、内存等的影响极小,主要考察核内流水线以及L1 Cache的性能表现。

Icestorm受制于较弱的后端执行单元规格,落后于其他两款CPU。虽然Icestorm是一款4发射处理器,但是仅配备了3组ALU单元,这对coremark的影响是巨大的;其偏弱的前端取指能力更是雪上加霜。
Verilator
以上三款测试集对处理器的前端压力较小,仿真大规模设计的verilator则恰恰相反,海量的分支与数MB的代码足迹能够轻松压垮ICache、BTB等组件,导致巨大的性能下降。

在这一项目中,尽管Icestrom频率最低但仍然胜出。采用分离式前端的A78与Gracemont受制于较小的前端规模,发生了海量的BTB miss;采用传统设计的Icestorm则将ICache视为下级BTB,因此取指效率更好。但是这样的设计在线程数增加后上限较低(参看下图,引入了Zen4作为对比);不过受限于苹果目前的核心簇互联设计,即便有配备了8个Icestorm的型号也无法获得可以参考的性能缩放数据。

前端
随着现代程序体量的膨胀,处理器面临越发巨大的前端压力;为了应对巨大的程序代码段带来的海量跳转指令,大部分高性能处理器核心的BTB容量、分支预测器容量不断扩展,分支预测算法不断演进。
BTB
对于采用了分离式前端(用英文表述decoupled branch prediction更为准确)的设计而言,BTB是前端的绝对核心组件;其负责在译码之前识别指令流中的跳转指令,并提供相应的跳转地址。过于频繁的BTB miss会造成严重的性能损失。但是Icestorm并没有采用当今更为普遍的分离式前端,其只有一级主BTB。

可见,Icestorm的L1 BTB容量为1024项,组相联。对现今的分离式前端设计而言,这样的BTB配置并不算大;不过对于传统前端设计这样的容量也算正常。决定BTB性能的远不止有效容量,其吞吐率、预测速度也十分重要。Icestorm并不支持每周期2 taken分支,不及A78和Intel的新产品12代、13代酷睿(GoldenCove等);在面对密集taken跳转代码块时Icestorm的表现会远远落后,但是这样的场景并不那么常见。
当分支数量超过1024后,图像变得混乱,即延迟波动十分巨大。此时Icestorm的L1 BTB已然失效,需要从ICache中取指并预译码才能获得分支指令信息,进而修正执行流;这带来了巨大的延迟损失,也是传统非分离前端设计的弊端。但是这样的设计也非没有优点,借助巨大的ICache,Icestorm无需配备独立的巨大下级BTB,省下了宝贵的片上空间并减少了功耗。尤其是对于低定位的处理器,其BTB容量一般会受到削减,分离式前端的效果也会有所折扣(面对前端压力大的负载时尤为明显);从verilator benchmark中我们也可以看到Icestorm在同定位处理器中的显著性能优势。
RAS
指令流中的call、return调用是较为特殊的分支指令情况,其栈形式的特征催生了专门用于预测此类场景的RAS(Return Address Stack)。简而言之,call指令压栈,return指令弹栈;而硬件栈(RAS)结构的深度就影响了处理器在复杂函数调用场景中的性能表现。

可见Icestorm的RAS容量为32项,对于小核而言这个深度极大,甚至比肩了X86桌面型号。可见苹果对于RAS的理解与ARM公版有一定的差异。至于图像的锯齿与波浪则反映了RAS溢出后其自恢复机制,此中的细节不在本专栏讨论;不过至少Icestorm配备了有效的自恢复机制,优于公版A78。
RAS CapacityIcestorm32A7816Gracemont2?(甚至可能没有传统意义的RAS)Zen432BP
分支预测器是当代高性能处理器前端中的又一核心组件,负责在流水线早期给出分支指令跳转与否的猜测,引导指令流的方向。在推测执行的超标量处理器中,分支预测器的准确率会极大影响处理器的性能和能效表现。


本测试考察分支预测器在不同历史pattern长度、不同分支数量(需要预测)情况下的准确性表现。Icestorm的分支预测器展现出了完全不同于A78的特性。
Icstorm分支预测器的等效有效容量甚至超过了A78,无论是在分支较少还是分支较多时,Icestorm都能追踪更长的历史。
Icestorm的分支预测器有较明显的Cascading特征。当分支历史超过一定长度后上级预测器的准确率下降,下级预测器开始接管,导致延迟小幅增长。下级预测器接管时取指流水线容易出现空泡,降低前端吞吐量;因此尽管Icestorm分支预测器的等效有效容量大于A78,实际表现可能反而不及。
总体而言Icestorm的分支预测器十分鲁棒,考虑到其自身定位就更为惊艳了。
IJP
IJP(Indirect Jump Predictor)作为BP(Branch Predictor)的一部分,负责预测间接跳转的地址。与预测跳转与否的BP不同的是,IJP需要在多个可能的跳转目标中选择本次的跳转目标,并引导指令流。


首先考察Icestorm IJP在不同历史pattern长度(但是可能目标均只有2个)、不同间接跳转数量(需要预测)情况下的准确性表现。Icestorm的IJP表现出了与BP不一样的特性,在间接跳转预测方面能力弱了许多,甚至不及A78。
Icestorm的IJP无法追踪较长的历史,在256后即丢失了预测能力。当然此处不是指其能够追踪256bit长的历史,而是通过与BP的数据对比可以看出其要么单独使用了较短的分支历史;要么是每条间接跳转指令需要在历史中占据较多的bit数,进而导致追踪能力变弱。
Icestorm的IJP同样有一定的Cascading特征。当分支历史超过一定长度后上级预测器的准确率下降,下级预测器开始接管,导致延迟小幅增长。
由于测试代码PC是2的幂次对齐,Icestorm的IJP在某些排布下似乎出现了hash冲突,导致行为不符合规律。
当分支数量超出256后,Icestorm的IJP基本丢失了预测能力,其IJP表项的数量应该是偏少的。
不过考虑到间接跳转指令在一般程序指令流中占比较少,Icestorm这样的取舍是也是可以理解的。


接下来,考察Icestorm IJP在不同可能跳转目标、不同间接跳转数量(需要预测)情况下的准确性表现。可见Icestorm IJP的表现十分糟糕,仅在最基本情况(2个可能的间接跳转目标)下能够较快处理间接跳转;一旦可能目标增多延迟立即退化。在这样的场景下Icestorm IJP使用的历史似乎已经短到不可思议,难以有效应对哪怕是分支数量极少且pattern历史也不长的情形,这里有多种可能性:
IJP自身的表项容量被配置得极少,也许苹果眼中corner case下的间接跳转性能并不重要。
IJP使用的全局历史十分短,或间接跳转目标地址占据了过多历史bit,使得等效历史长度变短。
IJP使用的历史中没有混合间接跳转目标地址bit。
此中的细节留到之后在隔壁专栏深入探究。
ITLB
TLB是现代处理器中容易被忽视的一个部件,其负责虚拟地址至物理地址的翻译。在一般情况下TLB并不会成为瓶颈,但是随着现代程序体量的膨胀TLB承受的压力也与日俱增,这一点在服务器负载中尤为明显。苹果本身并不将Apple sillion推向服务器市场,且MacOS原生使用16KB页(对TLB的压力天然减小),也许并未对TLB做过多优化。

Icestorm的ITLB容量为32项,取指时可以访问的L2 TLB容量为256项。其ITLB容量、L2 TLB容量均小于A78;在一般用户程序中这样的TLB规模并不会成为瓶颈。不过需要注意的是访问延迟的上涨点较为靠前,也许预示着某种特殊的替换算法或初级的TLB预取。
取指
处理器对程序的执行始于取指,前端的指令供给能力至关重要;一旦前端无法提供足够的指令,纵使后端的乱序执行能力再强也无力回天。对于Icestorm这样的四发射处理器,我们期望其每周期能够取指至少4条指令。

与主流(之前的ARM自研玩家为ARM公版、苹果、三星)不同,Apple对mop cache并不感兴趣,因此Icestorm也没有配备mop cache。我们可以看到指令足迹在128KB以内时由ICache供指,取指带宽为4条/周期;这样的带宽在分支较少时是完全够用的,但是无法与配备了mop cache的处理器比肩(例如A78的mop cache供指带宽为6条/周期)。出人意料的是,即便是小核心苹果也为之配备了128K的ICache,实属奢华。当执行流来到L2 Cache以后取指带宽骤然下降至2条/周期,可能预示着ICache较小的Refill通路位宽;相对得,A78的L2 Cache取指带宽相较ICache取指带宽并未严重下滑,仍然保持着~3.4条/周期的良好表现。与A78类似的是,Icestorm也似乎有意限制了代码段可以占据到L2 Cache(对于Icestorm已经是LLC)的容量,指令只能使用到一半左右的空间,而X86阵营并没有这类限制。当指令流进入SLC与内存段后取指带宽彻底雪崩,仅剩0.5条/周期或更低。

A78的mop Cache对于nop指令进行了压缩优化;倘若使用nop指令测试取指,mop cache每周期能够供给超过10条指令;Icestorm没有配备mop cache,自然也没有此类优化。
后端
处理器的后端负责指令的执行,当代高性能处理器普遍配备了乱序超标量机制,后端的设计也是纷繁复杂。
流水线宽度
在超标量处理器中我们着重关注前端与mid-core部分的宽度。
流水级宽度Fetch(ICache)4Fetch(mop Cache)no mop CacheDecode4Rename4Icestorm能够提供的最大取指带宽为4条指令/周期,后续的重命名级与译码级和取指宽度一致,因此Icestorm是最大吞吐为4条指令/周期的典型4发射处理器核。
执行单元
执行部件数量延迟ALU31BRU2MUL13DIV119(支持提前退出)AGU(ld+st)2AGU(ld)24AGU(st)1FPU2FADD23FMUL24FDIV19FMA24Icestorm只配备了3个ALU单元,不禁让人联想起A76,同样是4发射的A76也只配备了3组ALU(在随后的A77中补齐为4组)。简单ALU并不占据过多的面积,难度来自于物理寄存器堆读写端口的设计,这在更宽的处理器上会更加棘手,也许苹果出于控制寄存器堆复杂度的角度才缩减了ALU配置。Icestorm配备了2组BRU,在密集跳转应用中能够保证吞吐量,符合现代应用程序发展的趋势;配备2组BRU已经成为当今处理器核设计的趋势。乘除法单元上,Icestorm只配备了1组;其乘法器延迟较大,除法器算法也较为普通;除法器支持提前退出,当被除数变为0时算法可以提前结束。
Icestorm拥有2个AGU(访存地址生成单元),但是AGU load与AGU store并非分离式设计;2个AGU中1个支持load/store操作,1个只支持load操作。对于一款4发射处理器而言,这样的访存单元配置较为标准,但是与其他4发射处理器相比略微偏小,毕竟有一组AGU为load store共用。在memory wall越发明显的趋势下,重访存也是我个人十分欣赏的设计哲学;但是我个人更喜欢Intel式的AGU load与AGU store分离的设计,不过这也会显著增加发射队列、物理寄存器堆设计的复杂度,恐怕这也是Arm与苹果都未完全分离load与store AGU的原因。回到Icestorm上,没有配备第二个AGU store属实有些意外;客观上鉴于Icestorm的定位是不需要第二个AGU store的,但是苹果本可以使用相同的AGU单元减少重复设计。也许这样的偏执就是Icestorm能效比超高的秘密吧。
由于Icestorm的定位其只配备了两组浮点流水线。其FMADD延迟较低仅需4周期,FADD延迟表现一般需要3周期;考虑到Icestorm本身的目标频率也较低,这样的成绩较为平庸。与Arm公版(A78)不同的是,Icestorm的FMA单元不能支持较快的独立FADD操作,FMUL也似乎直接使用了FMA的流水线,苹果对于不重视的部分也抛弃得很彻底。FDIV的延迟较低。
总体而言Icestorm的后端执行单元配置偏重整数和分支,弱浮点向量,访存堪堪够用。
幕间
在下篇中我们将对Mid-core、访存子系统、核外系统进行逆向探究。
分析与测试:lyz、lxy
编辑于 2023-03-04 16:28
幕间
在上篇中我们主要探究了Icestorm微架构的取指前端和后端执行单元配置,下篇我们继续探究Mid Core、访存子系统、核外系统。
JamesAslan:Apple M1 Icestorm微架构评测(上):重铸小核荣光123 赞同 · 13 评论文章
Mid Core
重命名消除
在实际应用程序中许多指令并不需要进入处理器后端被真正执行(如move指令);现代处理器普遍配备了各式各样的重命名消除机制,以减少处理器后端压力并加速程序执行。
Elimination typeThroughputmove imm zero3move imm one4move chain1.2move single4move self4move bounce1.2sub self1xor self1Icestorm配备了基本的重命名消除机制,优于A78之流,但是与X86竞品相比仍较为落后。X86处理器倾向于配备极强的重命名消除机制,可能源自于其寄存器数相对较少的历史包袱。较为奇特的是,move置0似乎没有被特别消除,但是move置较小的立即数却被特别消除了,这是之后可以深入探究的一点。Icestorm的重命名可以消除不相关的move,但是不能在同一周期内处理move相关链;这样的取舍可以理解,一方面是在真实应用中这样的场景较少;另一方面是Icestorm流水线可能偏较短,支持相关链重命名会给重命名级带来巨大的时序压力。
move imm zero(mov x10, #0)吞吐为3说明重命名并未对置立即数0进行消除。
move imm one(mov x10, #1)吞吐为4说明重命名时对置立即数1进行了消除,因为其仅有3个ALU。
sub与xor均未对置0情况进行特别优化,可能是ARM ISA的编译器极少进行此类操作;X86处理器普遍配备此类优化。
move single(非相关的move消除)等的吞吐为4,超过了ALU数量(因此move并未由后端真正执行),说明其具备基本的重命名消除机制。
move bounce与move chain等的吞吐为1.2,说明后端出现了数据相关或前端重命名吞吐量下降,无论如何均表明未被重命名消除。
乱序资源
乱序推测执行的处理器需要海量的队列空间来跟踪指令,确保指令最终的提交顺序正确。
IcestormA78ROB~108~160PRF(integer)~108~160PRF(float)~112~92PRF(conditional bit/flag)~36~44如果说ARM的A78贯彻了中核的定位采用了小而美的设计,那么Apple的Icestorm则将“节俭”推向了极致。不过Icestorm的数据不能与A78进行直接横向对比,因为Icestorm使用了与其他处理器核有较大差异的基础结构。
Icestorm的ROB表项可以存储多条指令但是存在一定的限制,如:只能有一条指令发生回滚,具体机制仍需精细试验刻画。
由于上述ROB设计,Icestorm的PRF相对ROB并非简单的超额或足额,只能说较为均衡。
Icestorm的重命名信息有单独表项存储,并非存储在ROB中,该表项的大小为约108项;从这一角度来看Icestorm的PRF是足额的。
虽然提供了足额的浮点物理寄存器堆,但受制于浮点执行单元的性能限制,Icestorm的浮点性能表现并不优秀。由于ARM ISA定义了Conditional Bits,该结构也支持重命名操作,其容量在36项左右。本专栏提及A78的Mop Cache和ROB对Nop指令进行了特殊优化(每个mop cache项和ROB项可以存储多条Nop指令);Icestorm的ROB也对Nop指令进行了优化:
使用精心配比的非Nop指令占满ROB时得到下图:

乱序推测执行的处理器最为直接的调度窗口由各级发射队列的容量决定:
IcestormA78IssueQ+DispatchQ (Simple fix)~36~56IssueQ+DispatchQ (Complex fix)~14~32IssueQ+DispatchQ (Float)~32~48IssueQ+DispatchQ (Load)~20~32LDQ~54~64STQ~40~48苹果的发射队列采用了2级设计,在传统IssueQ之前放置有DispatchQ;DispatchQ为近FIFO结构,其中的指令不接受乱序调度。我们此处没有分离DispatchQ与IssueQ的容量,其实Icestorm的DispatchQ容量为~6项。DispatchQ的容量并不是在任何微结构中都可以探测的;苹果的DispatchQ容量可知是因为其入口带宽与出口带宽不等。每周期每个IssueQ只能接受1条来自DispatchQ的指令。
整数发射队列为36项左右,相较firestorm大幅缩减。整数发射队列与ROB表项的比值为36/108=0.33,是相当高的;这是较为平衡的设计,可以认为代表了一般场景下较好的乱序调度能力。
复杂整数指令如乘法指令所享受到的发射队列项数只有约14项;这是分布式发射队列的特征,每个执行单元前有一个独立的发射队列,且只有一个乘法执行单元。分布式发射队列的有效容量在极端情况下不及集中式发射队列,因此尽管icestorm整数发射队列与ROB表项的比值为36/108=0.33,与A78相仿,但是实际调度效果上是不及的。
浮点发射队列为36项左右,相较firestorm大幅缩减。对于Icestorm这样的设计而言是富足的,尤其是考虑到Icestorm的浮点执行单元本身规格一般。
访存发射队列为20项左右,相较firestorm大幅缩减。对于Icestorm这样的设计而言是合理的,但对访存能力的追求永无尽头。
总体而言,Icestorm的乱序调度窗口(去除DispatchQ容量以后)并不算很大,发射队列的配置甚至让人回想起上古AMD K10。
Icestorm的Load Queue容量为54项,Store Queue容量为40项。需要注意的是,本专栏对LDQ与STQ的计数并没有减去IssueQ部分的容量;作为参考,C&C的相关数值也没有减去IssueQ部分的容量而dougallj的相关数值减去了IssueQ部分的容量。这样的规格甚至相距A78不远,从其他乱序资源的规模上来看,Icestorm的LDQ与STQ容量绰绰有余;从执行单元的规格上来看(2 load AGU、1 store AGU),Icestorm的LDQ与STQ容量也十分大。总体而言,Icestorm仍然是一款相当注重访存的微架构;较强的访存能力会让处理器在实际负载中获得较好的表现,而非仅仅是理论跑分战神。
访存
访存是体系结构永恒的话题与难题,访存性能直接决定了处理器性能的上限(甚至取指也受制于访存),访存子系统的表现体现了设计团队的综合实力(前端、后端)。为了缓解越发明显的缓存墙(memory wall)问题,现代处理器的访存子系统十分复杂;流水线内的LDQ、STQ,Dcache、DTLB,下级Cache、下级TLB,各级预取器等组件交织配合;尝试在延迟、带宽等多个维度提高访存性能。
load-store前递
当load指令命中STQ中还未来得及写回DCache的store指令(访问了相同的物理地址)时,配备了load-store forwarding的处理器无需等待store指令写回DCache后再执行load指令,而是可以直接将STQ中存储的相应数据发送至LSU,完成load指令的执行。

Icestorm的Store-to-load forwarding图像并不传统,对角线区域延迟高度统一,我们需要计算实际的执行周期数才能确定其是否存在store-to-load forwarding机制。Icestorm的运行频率为2GHz,因此4ns代表8个时钟周期,这一数字较为暧昧。相较其他配备了forwarding机制的处理器核,倘若此处发生了forwarding,那么8个时钟周期的延迟略大了一点,但又显著小于其他处理器核store-to-load forwarding失效的情况。那么此处可以有两种解释:
(个人倾向的高概率解释)Icestorm配备了store-to-load forwarding机制。与其他处理器核不同的是,前递粒度为8bit即1 Byte(STQ的查询和存储粒度为8bit);也就是说Icestorm可以从任何非对齐位置对partial overlay的load指令进行store数据前递,而无需等待store指令的数据写入DCache再重新执行load指令。这一设计十分激进。
Icestorm没有配备store-to-load forwarding机制。与其他处理器核不同的是,Icestorm的load指令回滚开销极小或根本没有发生load指令回滚,load指令在store指令写入Dcache后迅速访问Dcache并取得数据。这一设计十分巧妙(借助store order violation predictor或栈操作消除机制)。
当store和load操作地址跨行时,都不会带来额外的延迟损失,且forwarding(如果解释1成立)完美工作。这一惊人的特性是苹果特殊的DCache设计带来的。
Dcache端口
load-store forwarding图还包含了更多的信息,苹果与众不同的DCache设计展现出了惊人的特性。

load、store均不跨行时,每周期能够执行1组store-load指令对,符合Icestorm只有1个AGU store(共两个AGU)的设计。

load不跨行store跨行时,store写入Dcache的带宽没有降低,这一点十分不同寻常;此时每周期仍然能够执行1组store-load指令对。苹果的DCache除了8 Byte的分bank外还按照地址(cacheline)进行了interleave。大核firestorm拥有4个block共128KB容量;小核icestorm则削减至2个block共64KB容量。

按照cacheline interleaved(相邻2个cacheline会分布于2个不同的block)的2个block分别提供了1个写端口(共2个写端口),因此跨行store仅需同时调用不同block的写端口即可,不会影响带宽。那么可以预见得:

load跨行store不跨行时,load读取Dcache的带宽没有降低;此时每周期能够执行1组store-load指令对。
当两条load指令访问同一block的同一set的不同bank时,Icestorm的多端口实现没有采用体复制设计,而是采用了行内广播;同一行的数据会被广播至所有load。也就是说,倘若两条load指令访问同一block的不同set就会产生端口冲突。这一设计较为巧妙,规避了体复制造成的SRAM冗余;不过也可能造成某些极端情况下的带宽降低。
Cache延迟
我们使用多种访存模式访问逐渐变大的数据集(直至内存),以探究Icestorm的Cache层级设计、预取器效果、内存控制器效果。

Apple采用了2级Cache的特殊设计(舍弃了private L2),且小核心簇并不能高速访问所有L2(同时也是LLC)。在LLC之下还有内存控制器侧的SLC负责SoC数据互联。
DCache有效容量为64KB。
Icestorm小核心簇的有效L2Cache有效容量为3MB-4MB。
Linear Chain能做到无损预取。
存在开页预取器或类Region预取器。
内存延迟偏高,无法与高频调参后的DDR4内存相比。

可以看到在12MB左右的位置存在一次延迟跳变,与有效L2容量的差值正好约为8MB。这一数据也较为暧昧,无法确认是来自远端大核侧L2 Cache的影响还是下侧SLC的影响(因为大核侧的有效L2容量正好为8MB)。相对合理的解释是影响来自后者,即SLC的容量为8MB,这样的片上系统工作逻辑较为合理。
访存序
乱序推测执行的处理器中,store指令无法被推测执行但是load指令允许被推测执行,这就造成了访存的RAW和WAR问题。为了避免错误推测执行的load指令带来频繁的回滚或流水线清空,处理器内部普遍配备了访存违例预测器,预测可能会导致回滚和流水线清空的load指令,并强制这样的load指令不再完全推测执行。

Icestorm的访存违例预测器有12项容量,采用了较为传统的设计。现今处理器仍然广泛使用这样的传统设计而非store-set等机制(只有Intel的大核采用了类store-set设计),但是传统机制也有海量的设计细节,我们不在此展开。相较大核firestorm,Icestorm的表项容量经历了大幅缩减;作为参考,业内其余设计的容量普遍在32项左右。12项的容量对于SPEC06之类的benchmark已然足够,但是在实际应用中是否足够我个人还要给其打上一个问号。
访存并行度
在该测试项目中,我们考察处理器同时面对多个访存流时的表现。每个访存流均是随机且独立的,因此可以规避大部分预取器的影响,最大限度压榨核内流水线乱序结构、各级Cache乱序结构。


可见Icestorm的图像与A78明显不同,A78的图像相互交织、混乱难辨;Icestorm的图像清晰整洁。Icestorm较好地隔离了预取器等结构的行为,使它们不会相互干扰。可见对于Icestorm而言双流访存能够获得接近线性的带宽提升;8个流以内时吞吐量有明显的收益。在远端的内存段,最大的有收益流数量为16个,在现如今处理器中不算很多;随着访存流数量继续增长,内存带宽受到干扰略微下降。对于小核心而言这样的表现是极其优秀的,体现了处理器内部设计的扎实功底。
Pointer Chasing
Pointer chasing是现代高性能处理器中常见的访存优化,当一条load指令的结果用于下一条load指令的地址计算时,该结果会从快速通路进入AGU流水线,缩短这两条load指令的执行间隔。在配备了pointer chasing优化的处理器中,触发pointer chasing后load-to-use延迟会比正常情况减少1周期。
Load-to-use latencyPointer-chasing Case3No-pointer-chasing Case4
Icestorm的核内访存系统继承了firestorm的特性,配备了pointer chasing优化。Icestorm4周期的访存延迟本身就较低,pointer chasing优化后的load-to-use延迟仅为3个时钟周期,更为惊艳。这不仅仅需要强大的逻辑设计能力(从苹果的专利来看,其中有很多细节),还需要强悍的物理设计能力。
核外
随着摩尔定律的放缓,即便是消费级处理器也被迫向多核方向发展,核外组件发挥着重要的作用。核外系统是个纷繁复杂的世界,无论是总线结构、一致性协议、LLC设计还是内存控制器调度,每项都复杂到读完1本书都无法入门。因此,我们只关注其中较为浅显、直观的部分。
核间延迟
我们通过CAS测量Soc中两两核间的延迟,其反映了处理器的一致性协议效率、LLC设计、总线设计等多个维度特性的交叠。


M1的核间延迟表现较为奇怪。大小核簇内部均能够有效地共享信息(传递脏数据),但是大小核簇之间并不能有效得共享信息。因此M1并没有采用Dynam IQ式的扁平crossbar类互联,大小核簇间很可能只能通过SLC及以下的结构传递脏数据。核心簇内40ns左右的延迟在如今是较慢的水平,不过对于消费级而言绰绰有余;核心簇间160ns的延迟简直匪夷所思,超过跨socket互联延迟,表现极其糟糕。我们甚至有理由怀疑此处数据被写回了内存再被读出;不过考虑到firestorm与icestorm调度的单向迁移特性,这一点也似乎可以强行解释。
当然,这里的数据异常也可能是测试方法导致(虽然不同渠道的不同结果能够相互映证,但是还是不能彻底排除这一可能),需要日后进一步排查。
访存带宽
我们通过Stream程序测试Soc中CPU单核的访存带宽,其反映了处理器核内的流水线设计、各级Cache设计、总线设计、内存控制器设计等多个维度特性的交叠。
Icestorm:
FunctionBest Rate (MB/s)Copy27731Scale27698Add29834Triad29557配备了大位宽LPDDR的M1的内存带宽理应极高,但是小核实测数值却十分低,我们不禁怀疑是小核簇的某些结构位宽限制了访存带宽,或是QoS机制不允许小核使用全部内存带宽。测试大核访存带宽如下:
Firestorm:
FunctionBest Rate (MB/s)Copy58026Scale58192Add55090Triad54843果然大核的带宽极高。icestorm在SPEC06中浮点性能偏弱,内存带宽限制难脱其责。
总结
自从2011年Arm v8横空出世,Arm公版就执着于顺序流水线小核心,A53、A55无不是这样的产品;但是随着十数年间移动端对性能的不断渴求,顺序双发射微架构逐渐力不从心。让人意想不到的是,伴随Arm v9而来的A510仍然是一款顺序流水线产品,牛津团队甚至将其扩展到了三发射规格。安卓小核在人们心目中的印象也逐渐固化为性能孱弱、功耗平庸、难堪大用。但是苹果自研架构的攀登之旅让我们有机会看到了山另一边的故事。原来小核心也可以性能喜人的同时功耗极低,完美承接后台任务与系统任务,与大核心配合无间,一起缔造了M1的能耗比传奇。已然站在高峰的苹果并没有停滞步伐,次年的迭代产品Blizzard将让我们看到山巅更高更远的青空,不过这已是后话。高通Nuvia似乎已跟进苹果的步伐,采用乱序微架构的能效核心;Arm公版也将于今年更新A510为A520,这恐怕是史上最短的公版小核更新周期,让人不禁期待其将采用怎样的微架构。后M1时代群雄并起,逐鹿中原;盛宴难再,幸甚快哉。
分析与测试:lyz、lxy
测试平台
本文的测试是在Mac mini M1上进行的,其使用了Apple M1(配备了4颗firestorm大核心和4颗icestorm小核心),环境为Arch Linux。

由于担心过热降频,因此没有使用Macbook Air。Mac mini对于想体验苹果产品的人来说性价比极佳,更新M2款后更是如此;搭配学生优惠仅需3699,整体涨价环境中的一股降价清流。不过目前Arch Linux还未适配M2款Mac mini,我们的基准跑分数据库无法录用MacOS下的分值(由于无法控制调用库,我们在MacOS下的跑分相较Linux都有一定的提升,故不能直接比较相对差异),因此Blizzard与Avalanche的评测仍需等待。
发布于 2023-03-11 10:33