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

10.10. 部分寄存器访问

一个通用寄存器的不同部分可以保存在不同的临时寄存器中,以避免假的依赖性。在写一个寄存器的一部分,后跟读该寄存器更大一部分时,出现一个问题:

; Example 10.4. Partial register access

mov al, 1

mov ebx, eax

Haswell与Broadwell解决了这个问题,没有可见的性能损失。也许它进行了部分寄存器与完整寄存器的双重簿记。

如果修改了其中一个高8位寄存器(AH,BH,CH,DH),然后读该寄存器更大一部分,情形就不同了:

; Example 10.5. Partial register problem with AH

mov ah, 1

mov ebx, eax

这里,插入一个额外的μop,在MOV EBX, EAX指令前面,将AH与EAX余下部分组合为单个临时寄存器。这导致了一个时钟周期的额外时延。

标记寄存器的部分访问

当标记寄存器一部分被修改,随后读该寄存器更大一部分时,出现类似的情形。这些情形中的某些,像例子10.5那样,要求一个额外μop。

; Example 10.6. Partial flags access

inc eax                         ; modifies zero flag but not carry flag

jbe L1                           ; reads both sero flag and carry flag

 

; Example 10.7. Partial register access

bt eax, 2                       ; modifies carry flag but not zero flag

cmovbe eax, ebx        ; reads both carry flag and zero flag

在这些情形里,处理器将插入一个额外的μop来聚合标记寄存器的这两个部分。

在像这样的情形中,你可能认为这是一个编程错误,或者是使用单条指令对两个不同条件进行检测的、深思熟虑的测试。

在一个偏移或旋转指令后读标记寄存器,没有惩罚或额外的μop。

向量寄存器的部分访问

在重排缓冲中,一个XMM寄存器不会被分解。因此,无需额外的μop,在写XMM寄存器一部分时,没有部分访问暂停。但写向量寄存器一部分时,有对该寄存器之前值的一个依赖。参考例子8.8,第103页。

YMM寄存器的两部分在VEX指令中不会被视为无关的,但当在VEX与非VEX模式间切换时,这两部分可以分开。如章节9.12所述,在混合VEX与非VEX代码时,有70时钟周期的惩罚。

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

缓存

HaswellBroadwell

μop缓存

每核1536μop,8路,每行6 μop

1级代码

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

1级数据

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

2

每核256kB8路,512组,每行64B,时延12

3

每核2 – 45MB12 – 16路,每行64B,时延32,共享

表10.2. Haswell与Broadwell上的缓存大小

每个核有一个缓存,除了最后一级缓存。在可以运行两个线程的核上,所有的缓存在这两个线程间共享。将来可能有更多的版本有别的3级缓存大小。某些版本有一个4级缓存。256位的读写总线(参见第127页),使得使用256位寄存器拷贝或置零大的内存块优势明显。仅当源与目标都32字节对齐时,REP MOVS指令才能发挥完全的能力。在其他所有情形里,最好调用使用256位寄存器的库函数。

缓存库冲突

在之前的处理器中,缓存库冲突现象是一个性能问题。这个问题现在已经消除了。在同一时钟周期里,总是可以进行两个缓存读,而不会导致缓存库冲突。

不过,具有相同组及偏移的内存地址之间的假依赖性问题仍然存在。不能同时读、写相隔4K字节倍数的地址:

; Example 10.8. False memory dependence

mov [rsi], eax

mov ebx, [rsi+1000H] ; False memory dependence

访问非对齐内存

非对齐内存的访问几乎没有惩罚,除了使用多个缓存行的影响。

​​​​​​​10.12. 写转发暂停

在某些条件下,处理器可以将一个内存写转发给相同地址的一个后续读。写转发工作在以下情形里:

  • 一个64位或更小的写,后跟一个相同地址、相同大小的读时,不管对齐。
  • 一个128或256位的写,后跟一个相同地址、相同大小的读时,完全对齐。
  • 一个64位或更小的写,后跟一个完全包含在写地址范围、更小的读时,不管对齐。
  • 在一个任意大小的写,后跟两个一半大小的读,或四个四分之一大小的读等时,这些读在内存地址范围里自然对齐。
  • 在一个对齐的128或256位写,后跟一个不跨越8字节边界、64位或更小的读时。

如果内存块跨越了64字节的缓存行边界,出现一个2时钟周期的时延。如果所有数据都自然对齐,这可以避免。

在以下情形里,写转发失败:

  • 一个任意大小的写,后跟一个更大的读时。
  • 一个任意大小的写,后跟一个部分重叠的读时。
  • 一个128位的写,后跟一个跨越两个64位半部边界的更小的读时。
  • 一个256位的写,后跟一个跨越两个128位半部边界的128位读时。
  • 一个256位的写,后跟一个跨越四个64位部分边界中任意一个的64位读时。

相比成功的写转发,失败的写转发需要多10个时钟周期。在一个没有对齐到至少16字节的128或256位的写之后,惩罚会高得多——大约50个时钟周期。

​​​​​​​10.13. 多线程

某些版本的Haswell与Broadwell可以在每个核中运行两个线程。这意味着每个线程仅得到一半的资源。

资源以与Sandy Bridge相同的方式(参考第120页),在同一个核里运行的两个线程间共享。一个小的差异是,两个线程间存在一个循环缓冲。

如果任何共享资源是性能的限制因素,每个核运行两个线程没有好处。有如此多的执行端口与执行单元,执行很少成为限制因素。如果代码旨在达成每时钟周期超过两条指令,或者如果缓存大小是一个限制因素,那么在每个核上运行两个线程没有优势。

在CPU中,没有办法给一个线程高出另一个线程的优先级。

​​​​​​​10.14. Haswell与Broadwell中的瓶颈

指令获取与解码

指令获取速率仍然限制在每时钟周期16字节,对不能很好放入μop缓存的代码,这可能是一个瓶颈。

μop缓存

对最多包含大约1000条指令的循环,μop缓存是高效。

在CPU密集代码中充分利用μop缓存是重要的。如果平均指令长度超过4字节,适合μop缓存的循环与不适合的循环之间的性能差异会相对显著。

μop缓存有与Sandy Bridge一样的缺点,如第109页与121页所述。

执行端口与执行单元

执行端口与执行单元的能力相当高。大多数常见的整数指令有4个执行单元可选,大多数浮点与向量指令有2个执行单元可选。因此,如果代码没有长的依赖链,获得每时钟周期4条指令的吞吐率是现实的。

几乎所有的向量执行单元与数据通路有完整的256位宽度。这使得使用256位向量寄存器以及AVX或AVX2指令集,非常有优势。

新的AVX2收集(gather)指令能高效地把非连续数据收纳入向量中,以及高效地向量化基于表的查找函数。在Broadwell中收集指令比Haswell更高效。

融合乘加(FMA)指令有助于提升浮点代码的性能。

在大多数情形里,寄存器到寄存器的移动被消除为0时延。

浮点加法吞吐率低于乘法

浮点向量乘法与FMA操作的吞吐率是每时钟周期两个向量操作,但浮点向量加法的吞吐率仅是每时钟周期一个向量操作。有两个乘法/FMA单元,但仅有一个加法单元,这很奇怪,因为通常在浮点代码中,加法比乘法更常见。如果代码包含的加法比乘法或FMA指令多,浮点的性能将是次优的。在我看来,对典型的浮点代码,这不是最好的设计,但至少它使Intel能夸口每时钟周期32 FLOPS的浮点性能。

对主要包含浮点加法的代码,把加法替换为带有一个乘数1.0的FMA指令,可以事实上提升吞吐率。FMA指令有时延5与每时钟周期两条指令的吞吐率,这意味着可能需要10个累加器寄存器来获得最大吞吐率。

执行时延与依赖链

执行时延通常是低的。大多数整数ALU操作仅有1时钟周期的时延,即使对256位向量操作。浮点加法时延为3,在Broadwell上浮点乘法的时延是3,在Haswell上是5。在长的依赖链中,这些执行时延是关键的。

分支预测

分支目标缓冲与分支预测器的结构未知,但至少预测率看起来不错。

被采用分支的吞吐率是每时钟周期一次跳转,或每2个时钟周期一次跳转,依赖于分支的密度。被预测不采用的分支有更高的、每时钟周期2次的吞吐率。因此,组织分支,使它们不被采用的可能性最大,是有好处的。

内存访问

相较于之前的处理器,内存端口的宽度被加倍了。到1级缓存的最大吞吐率,现在是每时钟周期2个32字节读以及一个32字节写。这使得以每时钟周期32字节的速度拷贝内存块成为可能。2级缓存的吞吐率远逊于此。

在之前的处理器上,缓存库冲突是一个相当常见的性能问题。在Haswell与Broadwell上。这个问题被完全解决了。

多线程

大多数关键资源在线程间共享。这意味着在多线程应用中,瓶颈变得更为关键。

文献

Intel: "Intel 64 and IA-32 Architectures Optimization Reference Manual". July 2013.

David Kanter: "Intel’s Haswell CPU Microarchitecture". November 2012. http://www.realworldtech.com/haswell-cpu/

Anand Lal Shimpi: "Intel's Haswell Architecture Analyzed: Building a New PC and a New Intel". October 2012. http://www.anandtech.com/show/6355/intels-haswell-architecture

Anna Filatova: "4th Generation of Core Microarchitecture: Intel Haswell". September 2012. http://www.xbitlabs.com/articles/cpu/display/haswell-uarch-idf.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值