Intel, AMD及VIA CPU的微架构(37)

19. AMD Ryzen流水线

19.1. AMD Ryzen中的流水线

新的Zen微架构是AMD处理器的一个完全重新设计,而且相当成功。使用Zen架构的第一个处理器称为Ryzen。它有4到8个核,每个核可以运行两个线程。每个核的吞吐率是如此的高,它可以同时处理两个线程,而没有严重的瓶颈。

19.2. 指令获取

一个执行单元里的两个核共享指令获取器。根据AMD文档,指令获取器每时钟周期可以从1级代码缓存获取32字节对齐的代码字节,但最大测得吞吐率每时钟周期仅高于16字节,很少超过17。

19.3. ​​​​​​​指令解码

指令边界没有在代码缓存中标记,不像之前的AMD处理器。解码器每时钟周期可以处理4条指令,包括产生两个μop的指令。流水线余下部分每时钟周期可以处理6个μop。

如果至少一半指令产生两个μop,可以获得每时钟周期6个μop的最大吞吐率。

产生超过两个μop的指令使用微代码。这些指令至少需要2时钟周期解码,因此吞吐率不会超过每2时钟周期一条复杂指令。每条指令产生的μop数,在手册4“指令表”中列出。

有许多前缀指令的解码,没有惩罚。这包括所有类型的前缀。

19.4. ​​​​​​​指令融合

后面紧跟着一个条件跳转的一条CMP或TEST指令,可以融合为一个μop。这适用于所有版本的CMP与TEST指令以及所有的条件跳转,除非CMP或TEST指令有一个rip相对地址,或者同时有一个位移与立即数。参考第178页例子18.1。其他ALU指令不能与条件跳转融合。

融合分支指令,如果没有被采用,可以每时钟周期两个这样的分支的吞吐率执行,如果采用,每2时钟周期一个分支。

19.5. ​​​​​​​μop缓存

对已解码指令,处理器有一个额外缓存。大小显示为2048个μop,每行8个μop。对保存最关键的循环,这足够大了。

对能放入μop缓存的循环,测得的吞吐率是每时钟周期5条指令。仍然可以从μop缓存以这个吞吐率发布双指令,因此以每时钟周期6个μop吞吐率,执行μop是可能的,这受到μop队列的限制。如果两个μop是类似的,双指令可能仅在μop缓存中使用一个项。

19.6. ​​​​​​​μop队列

在寄存器重命名与调度器之前,有一个未知大小的队列。这个队列从μop缓存或直接从解码器接收已解码μop。

19.7. ​​​​​​​栈引擎

处理器有一个重命名栈指针的高效栈引擎。它放在μop队列后面。

Push,pop与return指令仅使用一个μop。就栈指针而言,这些指令有零时延,使得后续依赖于栈指针、作为操作数或指针的指令不会被推迟。没有观察到在Intel处理器中看到的额外栈同步μop。

19.8. ​​​​​​​寄存器重命名与乱序调度器

在μop队列后,μop被分到两个单元。一个通用寄存器上指令的整数单元处理,以及一个处理浮点与向量指令的浮点单元。每个这些单元有自己带有寄存器重命名、调度及几个执行单元的寄存器文件。

整数寄存器文件有168个64位物理寄存器。浮点寄存器文件有160个128位寄存器。

在行进中,调度器可以保存总共192个μop。在1时钟周期可以回收8个μop。

19.9. ​​​​​​​整数执行流水线

整数单元有4个ALU,因此它可以每时钟周期执行4条整数指令。简单整数指令可由这4个ALU中的任一个处理,而某些代价更高的操作,比如乘法与除法,仅可由其中一个ALU处理。

除了4个ALU,整数单元有两个地址生成单元(AGU)。除了ALU,带有内存操作数的指令还使用一个AGU。读-修改与读-修改-写指令不分解为多个μop,但同一个μop同时去往ALU与AGU。在同一个时钟周期中,进行两次内存读,或者一次读与一次写,但不是两次写,是可能的。

19.10. ​​​​​​​浮点执行流水线

有4个浮点/向量执行流水线。这些流水线每个包含用于以下目的的执行单元:

操作

P0

P1

P2

P3

整数加法

x

x

 

x

整数乘法

x

 

 

 

浮点加法

 

 

x

x

浮点乘法与FMA

x

x

 

 

浮点除法与平方根

 

 

 

x

布尔逻辑

x

x

x

x

偏移

 

x

 

x

封装,排列

 

x

 

x

混合(Blend

x

x

 

x

加密

x

x

 

 

转换

 

 

 

x

内存写

 

 

x

 

表19.1. Ryzen浮点与向量执行流水线

简单的整数向量指令,比如加法、偏移与布尔指令,相比之前AMD处理器上的2时钟周期,仅有1时钟周期的时延。浮点加法有3时钟周期时延。对单精度,乘法有3时钟周期时延,对双精度有4时钟周期时延。融合乘加(FMA)有5时钟周期时延。吞吐率是每时钟周期两个128位加法与两个128位乘法。FMA指令使用与乘法相同的流水线,它们也部分占据加法单元。混合的FMA与加法指令的测得吞吐率是每时钟周期4条128位FMA指令与4条128位加法。

256位指令被分为两个μop,因此256位向量的吞吐率是128位向量吞吐率的一半。大多数指令可在两条或更多流水线间选择,如表19.1所示,因此大多数256位指令可以每时钟周期至少1条指令的吞吐率执行。

储存单元没有加倍。因此,256位写的吞吐率是每时钟周期一个。

不再支持XOP,TBM与3DNow指令。FMA4指令工作正确,虽然没有正式支持它们,且CPUID指令不报告它们。

次正规操作数

给出一个次正规结果的浮点操作需要额外几个时钟周期。在乘法或除法下溢到零时也一样。这远小于Bulldozer与Piledriver上高惩罚。在同时打开flush-to-zero模式与denormals-are-zero模式时,则没有惩罚。

19.11. ​​​​​​​AVX指令

Ryzen支持AVX2指令集。256位AVX与AVX2指令被分为两个每个处理128位的μop。大多数256位指令的吞吐率是每时钟周期1指令,因为有两个乘法单元与两个加法单元。256位指令以每时钟周期4条指令的速度解码。因此,在指令获取与解码是瓶颈时,使用256位指令比128位指令更高效。

在单线程中,浮点计算的最大吞吐率是每时钟周期一个256位向量乘法或FMA指令与一个256位向量加法。

在这个处理器上,混用AVX与非AVX向量指令没有惩罚。

19.12. ​​​​​​​不同执行域间的数据时延

向量单元中执行单元分为两个域,一个整数向量域与一个浮点向量域。在整数向量域一个μop的输出用作浮点域一个μop的输入时,有额外1时钟周期的时延,反之亦然。

例如,如果一条ADDPS指令的输出用作一条POR指令的输入,有额外1时钟周期的时延。可以通过等效的ORPS指令替换POR指令来避免这个时延。大多数浮点指令位于浮点域,除混排等指令。

指令的域信息参考手册4“指令表”。

19.13. ​​​​​​​没有时延的指令

寄存器到寄存器移动在寄存器重命名阶段解决,无需使用任何执行单元。这些指令有零时延。每时钟周期执行这样6条指令是可能的,甚至可以在一个时钟周期里重命名同一个寄存器7次。

在使用寄存器操作数时,以下指令有零时延:MOV,XCHG,FXCH,(V)MOVDQA,(V)MOVDQU,(V)MOVAPS,(V)MOVUPS,(V)MOVAPD与(V)MOVUPD。这适用于32位与64位通用寄存器以及128位xmm寄存器。它不适用8位与16位局部寄存器与mmx寄存器。使用256位ymm寄存器的移动有1时钟周期的时延,因为这个寄存器被分解为2个128位部分,在高半部使用一个执行单元进行移动时,仅低半部被重命名。

19.14. ​​​​​​​寄存器的局部访问

处理器总是将一个整数寄存器的不同部分保持在一起。例如,乱序执行机制不把AL与AH视为无关。因此,写一个寄存器局部的指令将对相同寄存器或其任一部分的之前值写,有一个假依赖。

写一个32位寄存器指令没有对相应64位寄存器的假依赖,因为64位寄存器的高半部被置零。

一个XMM寄存器的局部写有对整个寄存器的假依赖,但这不适用于YMM寄存器的两个半部。256位YMM寄存器被处理为两个无关的128位XMM寄存器。

处理器将某些算术标记处理为无关。例如,仅修改进位标记的指令没有对零标记的假依赖。

19.15. ​​​​​​​依赖打破指令

将一个寄存器置零的常见方式是XOR EAX, EAX或SUB EBX, EBX。处理器知道某些指令与寄存器的之前值无关,如果两个输入寄存器是相同的。以下指令被识别为与输入无关,如果两个输入操作数是相同的寄存器:XOR,SUB,SBB(仅依赖进位标记),CMP,PXOR,PANDN,PSUBx,PCMPEQx,PCMPGTx,XORPS,XORPD,ANDNPS,ANDNPD,但ANDN不是。

由于寄存器局部的处理,这不能作用于8位与16位寄存器,但它工作于32位与64位通用寄存器,以及各种尺寸的向量寄存器。一个寄存器与自身的浮点减法与比较从不被视为与输入无关,因为结果依赖于输入是否为NAN。

19.16. ​​​​​​​分支与循环

分支预测机制在第26页描述。对可高效预测的16字节代码中的分支数,没有限制。

通常跳转有每2时钟周期一个被采用跳转的吞吐率。这包括直接跳转,间接跳转,调用,返回与被采用分支。不过,最多5条指令的微循环可在1时钟周期里执行一次迭代。这里,融合的比较与分支指令算作1个。小循环的对齐与指令长度不重要,因为小循环包含在μop缓存里。

不被采用的分支有每时钟周期两个的吞吐率。

19.17. ​​​​​​​缓存与内存访问

缓存

Ryzen

μop

每核2k,8路,32组,每行8 μop

1级代码

每核64 kB,4路,256组,每行64 B。时延4

1级数据

每核32 kB,8路,64组,每行64 B。时延4

2级

每核512 kB,8路,1024组。时延17

3级

每4核16 MB,16路,8192组,每行64 B。时延40

表19.2. AMD Ryzen缓存大小

数据缓存有两个128位端口,可用于读或写。它可以在同一个时钟周期执行两次读或者一次读与一次写。到所有缓存级的数据带宽是256位(32字节)。有72个读缓冲与44个写缓冲。

当内存读的地址与前面一个写相隔0x1000倍数字数时,有一个假依赖。

在大多数情形里,自动硬件预取比显式软件预取更高效。

19.18. ​​​​​​​写转发暂停

对一个后续读的写转发在所有情形下工作良好,包括读一个写入数据的局部。非对齐读与写没有或很少惩罚,除了在跨越页边界时。与之前的写部分重叠的读有6 ~ 7时钟周期的惩罚。

19.19. ​​​​​​​多线程并发

处理器可以在每个核运行两个线程。这是合理的,因为每个核的吞吐率如此高,它很少被单个线程用完。

通常,在两个线程运行在同一个核里时,每个线程将得到一半的资源。μop队列平均地在两个线程间分配,因此每个线程得到最大吞吐率的一半。缓存、分支预测器、执行单元及大多数资源完全在两个线程间共享。

CPU核被组织为4个核一个的、称为CPU复合体(CPU complexe)的子单元。CPU复合体内的线程间通讯比CPU复合体间要快。

19.20. ​​​​​​​节能与倍频

Ryzen处理器通过时钟选通不使用的执行单元,进取地节能。时钟频率依据工作负荷与芯片温度自动改变。在我的测试中,在硬盘访问是限制因素,时钟频率通常低至通常频率的8%。在一非常长串CPU密集代码后,时钟频率增加到114%。在所有核都活动时,因为增加的温度,最大时钟频率不能维持。

获得一致的性能测量是困难的,因为时钟频率一直在剧烈变化。使用一个长的虚拟计算序列,有助于预热处理器,但时钟计数仍然不太对。用于测量小代码片段执行时间的时间戳计数器(TSC),以名义频率计数。处理器有另一个类似于Intel处理器的核心时钟计数器的,称为实际执行频率时钟计数器(APERF)。但是,APERF计数器仅能在内核模式中读取,不像运行在用户模式测试程序可访问的TSC。目前的报告基于以下方式计算的时钟计数:在运行测试代码前后,在设备驱动里读取TSC与APERF计数器。以这个方式获取的TSC与APERF计数的比例,用作一个适用于所有在测试代码运行期间得到的TSC计数的修正因子。这个方法是笨拙的,但结果看起来相当精确,除了在测试期间频率变化显著的情形。在手册4“指令表”中列出的时钟计数也是用这个方法得到的。测试代码可在www.agner.org/optimize/#testp获得。

19.21. ​​​​​​​AMD Ryzen中的瓶颈

在Ryzen中每个核的吞吐率比任何之前的AMD或Intel x86处理器都高,除了256位向量指令。合适μop缓存的循环有每时钟周期5条指令或6个μop的吞吐率。不能放入μop缓存的代码有每时钟周期4条指令或6个μop或大约16字节代码的吞吐率,取决于先到达谁。对有大循环的CPU密集代码,16字节的获取速度很可能是瓶颈。

大多数指令由2、3或4个执行单元支持,因此同时执行多条类型相同的指令是可能的。指令时延通常很低。

256位向量指令被分解为两个μop。因此,包含许多256位向量指令的代码片段可能受执行单元的限制。这里最大吞吐率是每时钟周期4个向量μop,或总计6个μop,如果至少三分之一μop使用通用寄存器。

在两个线程运行在同一个核上时,每线程的吞吐率是上面的一半。但每个核的容量比单个线程应用所需要大。因此,与类似的Intel处理器相比,Ryzen在多线程并发中更有优势。尽可能将线程间通讯保持在同一个4核CPU复合体内。如果你希望性能最优,Ryzen核极高的吞吐率,给予程序员与编译器额外的负担。显然,如果第二条指令依赖第一条指令的输出,不能并行地执行这两条指令。如果希望接近每时钟周期5条指令的最大吞吐率,避免长依赖链是重要的。

缓存相当大。这是一个显著的优势,因为在大多数情形下,缓存与内存访问最有可能是瓶颈。缓存带宽是每时钟32字节,小于与之竞争的Intel处理器。

文献

Mike Clark: "AMD and the new “Zen” High Performance x86 Core". Hot Chips Symposium, California. August 23, 2016.

Ken Mitchell & Elliot Kim: "AMD Ryzen™ CPU Optimization". Game Developers Confe-rence. San Francisco, March 2017.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值