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

14. Intel Knights Corner流水线

Xeon Phi/Knights Corner是Intel的集成众核(Many Integrated Core,MIC)系列中第一款处理器,在2012到2014以22nm工艺生产。它是一个有57 ~ 61个可以运行4个线程的核的协处理器,时钟频率1.1 ~ 1.2 GHz。

Knights Corner的指令集在引入时没有名字与CPUID比特。这是使用32个512位向量寄存器的AVX512指令的先驱。Knights Corner指令集非常类似于后来的AVX512指令集,但与后者二进制不兼容。Knights Corner向量指令与AVX512指令只有一个比特的差别。支持遗留x86与x87指令。后来,在它过时并被AVX512替代后,Intel将Knights Corner指令集命名为“初始众核指令(Initial Many Core Instructions,IMCI)”。

流水线没有乱序处理。基本流水线设计是一个基于旧式Pentium 1设计(参考第30页)、扩展到支持新向量指令的顺序、双重流水线。

解码器每时钟周期可以处理16字节或两条指令。当4条指令运行在一个核里时,每个线程将得到这个吞吐率的四分之一。

两个称为0-管道与1-管道,类似于Pentium 1里U-管道与V-管道的管道。0-管道可以执行向量与浮点指令,这两个管道都可以执行通用寄存器上的整数指令。

Knights Corner每个核有32 kB L1代码缓存,32 kB L1数据缓存,512 kB L2缓存,以及6 ~ 16 GB板上RAM。

我没有测过Knights Corner,但其他研究者已经测出浮点向量加法、乘法与FMA指令有4时钟周期时延,吞吐率是每核每时钟周期1条向量指令。达到理论最大吞吐率可能是困难的,因为Knights Corner缺乏乱序处理能力。

文献

"Intel Xeon Phi Product Family Performance". Intel, April 2013.

George Chrysos: "Intel® Xeon Phi™ Coprocessor - the Architecture". Intel Developer Zone, 2012.

Jianbin Fang, et al.: "Test-Driving Intel Xeon Phi". ICPE '14 Proceedings of the 5th ACM/SPEC international conference on Performance engineering. Dublin, Ireland. March 22-26, 2014. pp. 137-148.

扫描二维码关注公众号,回复: 5542698 查看本文章

Przemysław R. Karpiński: "Evaluation of Intel® Xeon Phi (Knight’s Corner) coprocessor’s core performance using VCL". Manuscript. CERN, 2014.

15. Intel Knights Landing流水线

Xeon Phi / Knights Landing是Intel集成众核(MIC)的第二代。它有64 ~ 72个可以运行4线程的核。以14 nm工艺构建,运行时钟频率是1.3 ~ 1.5 GHz。

每个核有32 kB L1代码缓存与32 kB L1数据缓存。每两个核共享1 MB L2缓存。封装内的16 GB MCDRAM由所有核共享。

Knights Landing是第一个支持AVX512指令集扩展的微处理器,这个指令集扩展将向量寄存器数从16加倍到32(仅在64位模式中),并将向量寄存器增加到512位,对比AVX中的256位与SSE中的128位。AVX512还增加了8个用于向量元素上条件操作的掩码寄存器。预期将来的桌面与膝上处理器将也支持AVX512,这使得MIC处理器与标准的PC处理器二进制兼容。

流水线设计基于Silvermont微架构,改进了乱序处理能力。最大吞吐率每时钟周期2条指令。

15.1. 流水线

对比Knights Corner顺序执行流水线,以及Silvermont不能乱序执行浮点与向量指令的流水线,Knights Landing有更好的乱序流水线。内存操作依次发布、乱序执行。而其他所有操作乱序发布、执行。

在解码器及寄存器重命名阶段,吞吐率限制在每时钟周期两条指令。解码器与重命名阶段中的双重流水线被分解为带有各自保留站的6条线路:两条用于通用寄存器上的整数指令,两条用于浮点与向量操作,两条用于内存操作。这使得在短突发中每时钟周期执行6个μop,而平均吞吐率限制在每时钟周期2个μop,成为可能。

流水线的实际长度未知,但可以基于分支误预测惩罚估算大致的长度。Knights Landing的流水线看起来与Silvermont的相同或稍长。

寄存器重命名与重排缓冲有72项。保留站有2 x 12项用于整数线路,2 x 20项用于浮点与向量线路,12项由两个内存线路共享。

15.2. 指令获取与解码

在代码缓存中标记了指令边界,以消除指令长度解码的瓶颈。

Knights Landing有两个解码器。最大吞吐率是平均每时钟周期两条指令或16字节。一个小缓冲允许在一个时钟周期里,解码最多24字节的孤立突发,但在多个连续的时钟周期里不能。函数入口与重要的循环入口可能16字节对齐,以优化指令解码。

不能将多条指令融合为一个μop。

简单指令从解码器仅产生一个μop。读-修改,读-修改-写指令从解码器产生一个送往内存单元与执行单元的μop。产生多个μop的指令使用微代码ROM,除了POP寄存器指令。使用微代码ROM的指令性能很差,通常需要7个或更多时钟周期解码。

带有超过3字节前缀及转义字节的指令,在解码器中,导致一个5 ~ 6时钟周期显著的时延。这个限制适用于标准前缀连同0F转义字节序列。这个限制很容易到达。所有属于SSSE3及更新的指令集的xmm指令,在指令码中,有一个前缀字节(66)及两个转义字节(0F 38或0F 3A)。如果在这样一条指令中使用任一r8 ~ r15或xmm8 ~ xmm15寄存器,那么需要一个额外的REX前缀,这样就可以超过3个前缀与转义字节的限制。例如:

; Example 15.1. Prefix limitation in Knights Landing

pblendw xmm1, xmm2, 2                            ; 1 prefix + 2 escape bytes. no penalty

pblendw xmm1, xmm8, 2                            ; 2 prefixes + 2 escape bytes = penalty

vpblendw xmm1, xmm1, xmm8, 2             ; 3-bytes VEX prefix. no penalty

对2与3字节VEX前缀,以及4字节EVEX前缀,没有惩罚,除非在这些之前有额外的前缀。一个VEX或EVEX前缀前的一个段前缀产生惩罚。对长度改变前缀,没有惩罚。

这两个解码器不能同时处理两条分支指令。为此,应该避免连续的分支指令。

15.3. ​​​​​​​循环缓冲

Knights Landing没有循环缓冲,不像Silvermont。这意味着指令的解码很可能成为瓶颈,即使对小的循环。

15.4. ​​​​​​​执行单元

在指令解码、寄存器分配及重命名步骤里,流水线都有两条线路。在寄存器分配与重命名步骤后,这些分岔为带有2条线路的3个单元:整数单元、浮点单元与内存单元。整数单元处理通用寄存器上的指令。浮点单元处理所有在浮点寄存器、向量寄存器及掩码寄存器上的指令。内存单元处理内存读与写。整数单元、浮点单元与内存单元都有两条线路,因此同时执行两条整数指令、或两条向量指令、或两条内存指令是可能的。所有在掩码寄存器上的操作都使用浮点单元。

单元/线路

操作

内存 0

整数与f.p./向量读写

内存 1

整数与f.p./向量读

整数 0

ALU,乘法,偏移

整数 1

ALU,跳转,lea

F.P. 0

向量加法、乘法、除法、逻辑、偏移、转换

F.P. 1

向量加法、乘法、逻辑

表15.1. Knights Landing中的执行单元/线路

在整数单元0页浮点单元0之间是共享的一个除法单元。浮点除法有固定的27 ~ 47时钟周期时延。整数除法时延不固定。

浮点/向量单元的时延

浮点单元中的所有指令有至少2时钟周期的时延,而整数单元里的简单指令有1时钟周期的时延,大多数其他Intel处理器,包括Silvermont,在浮点/向量单元有1时钟周期的时延。对浮点/向量单元中双倍时延的一个可能解释是,整数保留站可以保存源数据,而浮点保留站不能。这意味着一个整数ALU可以将其结果直接写入保留站中任何需要它的后续μop,而在浮点单元里的结果必须通过浮点寄存器文件。一个浮点μop可以有3个512位的输入操作数与一个16位掩码,总共1552数据比特。这可能在保留站里占据了太多空间。一个整数μop可以有不超过2个64位输入操作数及一个标记。即使在掩码寄存器上的简单操作也有2时钟周期时延,而整数单元上相同的操作仅有1时钟周期时延。

掩码操作

向量操作可以有一个掩码,因此掩码寄存器中的每个比特决定是否进行对应向量元素上的操作。掩蔽是硬件里一个不需要额外时间的简单操作。不管有没有掩码,所有指令有相同的时延与吞吐率。时序也与掩码值无关(即使对gather与scatter指令)。掩码寄存器与其他输入操作数同时读。在一个掩码寄存器是全零时,调度器不能节省时间,因为在从保留站调度μop时,掩码值还不可用。

掩码操作的时序可由以下例子说明:

; Example 15.2. Masked read in Knights Landing

vmovdqa32 zmm1{k1}, [rsi]

这条指令从由rsi指向的内存操作数读512比特,将它保存到512位向量寄存器ZMM1。操作数以32位粒度掩蔽,因此ZMM1中每个32位向量元素不改变,如果掩码寄存器k1中对应比特是0。

这里,从内存操作数到目标寄存器ZMM1的时延,大约是5时钟周期。从掩码寄存器k1到目标寄存器的时延是2时钟周期。还有对ZMM1之前值的一个依赖,因为掩码比特为0的元素将保留之前值。从ZMM1输入到ZMM1输出的时延是2时钟周期。换而言之,输出ZMM1在这三个事件的最后一个里可用:内存操作数5时钟周期后,或掩码寄存器k1后2时钟周期,或ZMM1输入可用后2时钟周期。

对目标寄存器之前值的依赖可以通过添加一个清零选项:

; Example 15.3. Masked read without dependence on prior value

vmovdqa32 zmm1{k1}{z}, [rsi]

在对应掩码比特为零时,{z}选项使目标向量中的元素为零,而不是不变。建议在可能避免对掩蔽指令目标寄存器之前值的依赖时,使用清零选项。如果没有掩码,没有对目标寄存器之前值的依赖。

数据旁路时延

在整数单元与浮点/向量单元间移动数据的指令有4 ~ 5时钟周期的时延。对在浮点数据上使用整数向量指令没有处罚,反之亦然。

组合、混排及其他几个指令,离开其他执行单元的一个独立单元里实现。自或至这个单元移动数据,有最多2时钟周期的时延。例如,在一连串类似指令中测量时,PALIGNR指令有2时钟周期的时延,但当输入来自另一个类型指令且输出去往另一个类型指令时,如移动或加法,时延是6时钟周期。额外的4时钟周期是移动数据到远处单元的2时钟周期,以及把结果移回通用单元的2时钟周期。某些混排指令,如VPUSHFB,有多个μop与非常长的时延。

下溢与次正规值

次正规值作为输入或输出,或产生下溢的一个除法,需要大约300时钟周期,除非同时使用了flush-to-zero模式与denormals-are-zero模式。在加法与乘法上的次正规值没有惩罚。

数学函数

Knights Landing支持一个包括某些强大数学函数的特殊指令集扩展,AVX512ER。VRCP28PS在8时钟周期里计算一个单精度向量的倒数。VRSQRT28PS在7时钟周期里计算一个平方根倒数。而VEXP2PS在10时钟周期里在一个单精度向量上计算一个基于2的指数函数。Intel手册对这些指令的精确描述有些混淆,但在我的测试里,在单精度向量上它们都精确到最后一个比特。仅在双精度向量上,它们仅是近似的。

AVX512ER使得Knights Landing非常适合具有大量单精度就足够的并行数据的数学计算,比如神经网络。

遗留x87指令有差的性能。特别是FXCH指令会导致性能问题,因为这条指令大量用在大多数x87代码里,它需要9时钟周期。不应该使用x87指令,除非需要长双精度。

15.5. ​​​​​​​寄存器的部分访问

一个寄存器部分写对寄存器余下部分有一个假的依赖。一个通用寄存器的不同部分总是视为相关的。

标记寄存器可处理为不同部分。在仅写某些标记为后,读更多标记位有1时钟周期额外时延。

15.6. ​​​​​​​向量寄存器部分访问与VEX / 非VEX转换

Knights Landing没有像Sandy Bridge那样的独立VEX模式(参考章节9.12)。相反,在一条修改向量寄存器低128位的非VEX指令,后跟一条读该寄存器256或512位的VEX指令时,它有一个部分寄存器暂停(参考章节6.8)。

VZEROALL或VZEROUPPER指令在这里不仅多余,它们实际上对性能还有害。一条VZEROALL或VZEROUPPER指令在64位模式里需要36时钟周期,在32位模式里需要30时钟周期。注意这破坏了之前的ABI建议。对之前处理器的建议是,VEX代码在调用或返回非VEX或VEX状态未知代码前,应该后跟一条VZEROUPPER。

15.7. ​​​​​​​无关的特殊情形

将一个寄存器置零的常见方法是与自己XOR或减去自己,如XOR EAX, EAX。Knights Landing处理器知道某些指令与寄存器之前值是无关的,但仅在以下情形里:

  • 一个32位寄存器与自身xor。
  • 一个向量寄存器与自身vpxor,vpxord,vpxorq,vxorps,vxorpd

它不能识别64位寄存器、mmx寄存器或掩码寄存器的无关性。不能识别减法及比较指令,及没有VEX前缀的向量指令的无关性。可以通过对应32位寄存器与自身xor,清零一个64位寄存器。

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

缓存

Knights Landing

1级代码

每核32 kB8路,64组,每行64 B

1级数据

每核32 kB8路,64组,每行64 B,时延4

2

1 MB16路,1024组,每行64,时延17。两核间共享。

封装MCDRAM

16 GB,时延~200。可选地配置为缓存。所有核间共享。

表15.2. Knights Landing的缓存大小

没有观察到缓存库冲突。在4kB倍数分开的内存地址间有假的依赖性。

对跨4GB边界的跳转、调用及返回有惩罚。

读写带宽

处理器每时钟周期可以进行两次内存读,或者使用最多512位向量寄存器的一次读与一次写。在同一时钟周期里,它不能进行使用通用寄存器的两次读,但可以同时进行使用任何寄存器类型的一次读与一次写。

向量寄存器的大小(512位)与缓存行大小(64字节)相同。因此,在一个操作里读或写一整行缓存行是可能的。对512位向量,在内存操作数对齐到缓存行时,即地址可被64整除,才能得到最大读写吞吐率。

15.9. ​​​​​​​写转发

一个内存写可以转发给相同起始地址、相同大小或一半对象的一个后续读。对通用处理器,写+后续读的时延是6 ~ 7时钟周期,对向量寄存器是9 ~ 10时钟周期。

在以下情形中,写转发识别

  • 跨缓存行边界的地址
  • 读的起始地址与写不同
  • 读的大小与写不同,或不是写的一半
  • 向量读/写不对齐
  • 从向量寄存器转发到整数寄存器,或相反
  • 写使用掩码

转发一个写到两个半部的两个读是不可能。一个失败的写转发需要16 ~ 20时钟周期。

15.10. ​​​​​​​多线程

Knights Landing在每个核可以运行4个线程。每个线程如下共享流水线与执行资源:

  • 1线程运行在一个核里:所有资源
  • 2线程运行在一个核里:一半资源
  • 3或4线程运行在一个核里:四分之一资源

2级缓存在两个核之间共享,即最多8个线程。

对性能受限于指令获取、解码或执行资源的CPU密集任务,每个核运行多个线程没有好处。

每个核运行多个线程有好处的唯一情形是在性能受限于内存访问、分支误预测或长时延依赖链时。

不幸地,在一个多用户或多进程环境里,控制每核的线程数是困难的。大量低优先级线程很容易耗尽大多数CPU资源,使高优先级线程以可能速度的四分之一运行。当前的操作系统不善于防止这个问题。最好的解决方案可能是在BIOS设置里关闭超线程。

15.11. ​​​​​​​Knights Landing里的瓶颈

指令获取与解码

解码无疑是设计中最弱的部分。解码器的吞吐率小于执行单元的最大吞吐率。这很可能成为CPU密集代码中的瓶颈。

微代码

产生多个μop的指令在微代码中实现,除了pop寄存器指令。所有微代码化指令需要7或更多时钟周期解码。在关键代码里避免微代码化指令很重要。例如,建议以一个内存操作数到寄存器的载入,后跟对寄存器的一个调用,替换带有一个内存操作数(函数指针)的调用。

某些微代码化指令非常低效。参考手册4“指令表”。在关键代码中避免最低效指令很重要。

执行端口与执行单元

向量执行单元有完整的512位带宽。使用512位向量指令有优势。

所有在浮点/向量单元里的指令有2个或以上时钟周期的时延,而在通用寄存器上的简单指令有1时钟周期的时延。

遗留x87形式浮点代码的性能很差。混排与组合指令有差的性能——其中一些非常差。

VZEROUPPER与ZEROALL指令需要36时钟周期。这是一个问题,因为之前的AVX代码包含许多这些指令。ABI建议必须修正这些指令的使用。

乱序执行

Knights Landing可以乱序执行指令,但用于重排指令的缓冲比当前桌面处理器小得多。它将不能最优地处理长依赖链,除非它们被分为多个线程。

分支预测

分支目标缓冲的大小未知。预测率尚可。误预测惩罚相对低。

通过使用掩码,可以避免向量代码中的分支。

内存访问

处理器每时钟周期可以执行两次内存读到向量寄存器,但到通用寄存器仅一次。写转发仅在简单情形里工作。内存操作顺序调度,即使乱序执行。

缓存性能良好。

多线程

处理器可以在每个核里运行4个线程。不过,对CPU密集代码这没有好处,因为解码器不够大,不能在单线程上保持执行单元繁忙。如果低优先级线程运行在相同的核,关键或高优先级线程以最大速度的四分之一运行,是一个严重的问题。在一个多用户或多进程环境里,这很难避免,除非在BIOS设置中关闭超线程。

文献

Intel 64 and IA-32 Architectures Optimization Reference Manual. 2016.

Avinash Sodani: "Knights Landing (KNL): 2nd Generation Intel® Xeon Phi™ Processor". Hot Chips: A Symposium on High Performance Chips. Cupertino, CA, August 23-25, 2015

James Jeffers, James Reinders, and Avinash Sodani: Intel Xeon Phi Coprocessor High-Performance Programming. Knights Landing Edition. 2nd ed. Elsevier, 2016.

猜你喜欢

转载自blog.csdn.net/wuhui_gdnt/article/details/86644429