13. Intel Silvermont流水线
在中仅有小打小闹的几年后,低功耗的Atom设计最终迈出了一大步。现在Silvermont处理器是ARM处理器的一个有力竞争者。对整数指令,它有有限的乱序执行能力,但对浮点与向量指令没有。它支持SSE4.2指令,但不支持AVX。
流水线有14级,而之前的Atom设计有16级。3级用于指令获取,3级用于指令解码,2级用于寄存器分配与重命名,1级用于调度,1及用于执行,4级用于回收与提交。更短的流水线据说将分支误预测惩罚降低到了10时钟周期,不过我的测试显示大约12个时钟周期,几乎与Atom相同。
芯片有1到4个带有2个执行核的单元,总共最多8线程。一个单元里的2个核共享2级缓存,但不共享流水线或执行资源。
13.1. 流水线
Slivermont有5条流水线:一个用于内存读写操作,两个用于整数操作,两个用于浮点与向量操作。最大平均吞吐率是每时钟周期两条指令,在两条指令去往不同的流水线时实现。
两个整数流水线可以乱序执行。每个整数流水线有可以在队列中保存8条指令的保留站。通过一个6项的保留站,内存操作也可以乱序进行,而浮点与向量操作在自己的流水线内不能重排。
13.2. 指令获取与解码
指令边界在代码缓存中标记。这是消除自Pentium MMX以来Intel没有使用的指令长度解码瓶颈的一个简单技术,而AMD始终使用指令长度解码。
Silvermont有两个解码器,每时钟周期可以获取及解码两条简单指令。超过8字节的指令有每时钟周期一条指令的吞吐率。大多数指令仅从解码器产生一个μop。读-修改及读-修改-写指令从解码器产生送往内存单元与执行单元的单个μop。产生多个μop的指令使用微代码ROM,除了POP寄存器与FXCH指令。所有使用微代码ROM的指令,如果去往解码器0,需要4时钟周期解码。如果这样一条指令首先去往解码器1,那么在2时钟周期的时延后,它被重定向到解码器0。这意味着,对产生2个μop且恰好首先去往解码器0的指令,解码过程需要6时钟周期。
带有超过3个前缀及转义字节的指令在解码器中导致严重的时延。不像Intel与AMD的大多数其他处理器,Silvermont不仅包括这个限制里的标准前缀,还包括像0F这样的转义字节。因此,这个限制很容易超出。所有属于SSSE3与更新指令集的xmm指令,在指令代码中,有一个前缀字节(66)页两个转义字节(0F 38或0F 3A)。如果任意r8 ~ r15或xmm8 ~ xmm15寄存器用在这样一条指令里,那么需要一个额外的REX前缀,这样就可以超过3个前缀与转义字节的限制。例如:
; Example 13.1. Prefix limitation in Silvermont
pblendw xmm1, xmm2, 2 ; 1 prefix + 2 escape bytes
pblendw xmm1, xmm8, 2 ; 2 prefixes + 2 escape bytes
在这个例子中的第一条指令通常在一个时钟周期里解码,而第二条指令,如果首先去往第一个解码器,需要4时钟周期解码,否则如果去往第二个解码器,需要6时钟周期。对长度改变前缀没有惩罚。
这两个解码器不能同时处理两条分支指令。为此,应该避免连续的分支指令。
13.3. 循环缓冲
Silvermont有一个回收已解码μop的循环缓冲。通过消除解码瓶颈,它可以提升最多29条指令循环的性能。
13.4. 宏操作融合
Silvermont不能将多条指令融合为单个μop。
13.5. 寄存器分配与乱序执行
在通用寄存器上的指令可以有效程度地乱序执行。显然,同时不能挂起超过8条指令。在浮点与向量寄存器上的指令,与去往相同执行端口及流水线的其他指令,不能一起乱序执行。但在一个流水线里的浮点指令可以绕过另一个流水线里的浮点指令。例如,一条浮点乘法指令(在FP0)可以在之前一条浮点加法指令(在FP1)前面执行。
相同的逻辑寄存器可以分配到不同的物理寄存器,以消除假的依赖。这也适用于浮点与向量寄存器,即使在相同的流水线中它们不能乱序执行。
13.6. 无关的特殊情形
将一个寄存器置零的常用方式是与自己XOR或减去自身,比如XOR EAX, EAX。Silvermont处理器知道,如果两个输入操作数是同一个寄存器,某些指令与寄存器之前的值无关。这仅工作在几个情形里。一个32位寄存器与自己的XOR被认为与之前值无关,但这不能作用于8,16或64位寄存器。因此,清理一个通用寄存器的最好方式是将该寄存器的32位版本与自身XOR。这将清除所有64位。SUB,SBB与CMP指令不能以这个方式察觉。一个向量寄存器可以通过PXOR,XORPS或XORPD指令,与自身XOR,清除对之前值的依赖,但不能通过减法、比较或其他指令。
13.7. 执行单元
Silvermont有5个带有自己调度器的执行端口:
端口 |
操作 |
内存 |
内存读写 |
整数端口0 |
ALU,乘法,偏移 |
整数端口1 |
ALU,跳转 |
F.P. 端口0 |
乘法、除法、偏移、封装、转换 |
F.P. 端口1 |
加法 |
表13.1. Silvermont中的执行单元
执行单元是部分流水线化的。整数乘法器连同浮点加法器与乘法器,对较小的数据,有每时钟周期一条指令的吞吐率,对较大数据,有每两时钟周期一条指令的吞吐率:
端口与单元 |
数据大小 |
时延 |
吞吐率倒数 |
IP0乘法 |
32位整数 |
3 |
1 |
IP0乘法 |
64位整数 |
5 |
2 |
FP0乘法 |
4个16位整数组成的64位向量 |
4 |
1 |
FP0乘法 |
8个16位整数组成的128位向量 |
5 |
2 |
FP0乘法 |
单精度浮点 |
4 |
1 |
FP0乘法 |
4个单精度组成的128位向量 |
5 |
2 |
FP0乘法 |
双精度 |
5 |
2 |
FP0乘法 |
2个双精度组成的128位向量 |
7 |
4 |
FP0/1加法 |
8,16,32位整数组成的向量 |
1 |
0.5 |
FP0/1加法 |
64位整数组成的向量 |
4 |
? |
FP1加法 |
单精度浮点 |
3 |
1 |
FP1加法 |
4个单精度浮点组成的128位向量 |
3 |
1 |
FP1加法 |
双精度 |
3 |
1 |
FP1加法 |
2个双精度组成的128位向量 |
4 |
2 |
表13.2. Silvermont中部分流水线化的执行单元
在整数端口0与浮点端口0之间共享一个除法单元。它有19到69个时钟周期的时延,没有流水线化。浮点除法有固定的时延。
内存带宽是每时钟周期一条128位读或写指令。每时钟周期进行一次读操作与一次写操作是可能的,但仅在这两个操作是同一条指令的部分时,如一条读-修改-写指令。在所有其他情形中,最大带宽是每时钟周期一次内存操作。
在整数单元与浮点/向量单元间移动数据的指令有3 ~ 4个时钟周期的时延。否则,在不同执行单元间移动数据没有额外的时延。另外,在浮点数据上使用整数向量指令没有惩罚,反之亦然。
以次正规值作为输入或输出,或者产生下溢的操作,需要大约160个时钟周期,除非同时使用flush-to-zero模式以及denormals-are-zero模式。
13.8. 部分寄存器访问
写部分寄存器对该寄存器余下部分有一个假的依赖。一个通用寄存器或向量寄存器的不同部分不视为彼此独立。
标记寄存器可处理为不同的部分。在写部分标记寄存器后,读任意标记,有1时钟周期的额外时延。
13.9. 缓存与内存访问
缓存 |
Silvermont |
1级代码 |
每核32 kB,8路,64组,每行64 B |
1级数据 |
每核24 kB,6路,64组,每行64 B,时延3 |
2级 |
1 MB,16路,1024组,每行64,时延19。线程间共享 |
表13.3. Silvermont上的缓存大小
没有观察到缓存库冲突。在4kB倍数隔开的内存间有假的依赖。
13.10. 写转发
一个内存写可以转发给后续一个在相同起始地址、相同大小或更小的读。写+后续读的时延是7时钟周期。如果一个非对齐写转发跨过缓存行边界,有一个额外的3时钟周期时延。
当读比写更大或者不在相同的地址开始时,写转发失败。将一个写转发给两个半部的读是不可能的。一个失败的写转发有额外的5时钟周期时延。
13.11. 多线程
Silvermont有一个或多个单元带有2个核。一个单元里的这两个核共享2级缓存。运行在同一个单元里的两个线程不会竞争除了2级缓存以外的资源。
13.12. Silvermont里的瓶颈
解码绝对是Silvermont设计中最弱的一环。产生多个μop的指令需要至少4时钟周期解码,很多时候需要更多时间(有少数例外)。这同样适用于需要一个额外前缀的指令。所有属于SSSE3及更新指令集的xmm指令需要4或6个时钟周期解码,如果它们使用了任意r8 ~ r15或xmm8 ~ xmm15寄存器。在对Silvermont的代码设计里,应该不惜一切代价避免在解码器中需要额外时间的指令。
大多数执行单元有完全的128位能力,但某些执行单元仅部分流水线化,对完整的向量或双精度数据,需要额外的时钟周期。
对小的低功耗处理器,执行单元的能力看起来令人满意。
Atom在遗留x87代码上令人崩溃的性能,最终被修复。
Silvermont有寄存器重命名,但对乱序执行有非常有限的能力。对获得最好性能,编译器的调度可能是必要的。
分支目标缓冲的大小未知。预测率一般。误预测惩罚相对低。根据我的测试,间接分支没有模式预测。
吞吐率是每时钟周期一个读/写指令。缓存性能良好。
除了2级缓存,线程间不共享关键资源。这使得多线程高效。
Intel: "Intel 64 and IA-32 Architectures Optimization Reference Manual”. July 2013.
Sebastian Anthony: “Intel’s Silvermont revealed: After a five-year snooze, Intel is finally ready to crush ARM”. http://www.extremetech.com/computing/155082-intels-silvermont-revealed-after-a-five-year-snooze-intel-is-finally-ready-to-crush-arm. 2013.
Anand Lal Shimpi: “Intel’s Silvermont Architecture Revealed: Getting Serious about Mobile”. http://www.anandtech.com/show/6936/intels-silvermont-architecture-revealed-getting-serious-about-mobile. 2013.
David Kanter: ”Silvermont, Intel’s Low Power Architecture”. http://www.realworldtech.com/silvermont/. 2013.