@peufeu的答案指出,这些是系统范围的聚合带宽。L1和L2是Intel Sandybridge系列中的每核专用高速缓存,因此数量是单个核可以达到的2倍。但这仍然给我们留下了令人印象深刻的高带宽和低延迟。
L1D缓存直接内置在CPU内核中,并且与加载执行单元(和存储缓冲区)紧密耦合。同样,L1I高速缓存就在内核的指令获取/解码部分的旁边。(我实际上没有看过Sandybridge的硅平面图,因此从字面上看可能并非如此。前端的问题/重命名部分可能更接近“ L0”解码的uop缓存,从而节省了功耗并具有更好的带宽比解码器。)
但是使用L1缓存,即使我们可以在每个周期读取...
为什么停在那里?自Sandybridge起的英特尔和自K8起的AMD可以每个周期执行2次加载。多端口缓存和TLB是一件事情。
David Kanter的Sandybridge微体系结构文章有一个不错的图(它也适用于您的IvyBridge CPU):
(“统一调度程序”保留ALU和内存微件,等待它们的输入准备就绪,和/或等待其执行端口。(例如,vmovdqa ymm0, [rdi]
解码为必须等待rdi
先前add rdi,32
尚未执行的加载uop ,对于例子)。 英特尔时间表微指令到在发布/重命名时间端口。此图仅示出了用于存储器微指令的执行端口,但未执行ALU的uop争夺这一点。该问题/重命名阶段增加了微指令到ROB和调度他们一直停留在ROB中直到退休,但直到调度到执行端口才在调度程序中使用(这是Intel的术语;其他人使用issue并以不同的方式调度)。 AMD为整数/ FP使用单独的调度程序,但是寻址模式始终使用整数寄存器
如图所示,只有2个AGU端口(地址生成单元,采用类似寻址方式[rdi + rdx*4 + 1024]
并产生线性地址)。每个时钟可以执行2个存储器操作(每个存储器128b / 16个字节),最多可以存储1个。
但它有一个窍门:SnB / IvB运行256b AVX作为单个uop加载/存储,在加载/存储端口中需要2个周期,但在第一个周期只需要AGU。这样就可以在第二个周期内在端口2/3的AGU上运行存储地址uop,而不会丢失任何负载吞吐量。因此,使用AVX(Intel Pentium / Celeron CPU不支持:/),SnB / IvB(理论上)可以在每个周期中承受2个负载和 1个存储。
您的IvyBridge CPU是Sandybridge的缩影(具有一些微体系结构上的改进,例如mov-elimination,ERMSB(memcpy / memset)和下一页硬件预取)。此后的一代(Haswell)通过将执行单元到L1的数据路径从128b扩展到256b,使每时钟L1D带宽增加了一倍,因此AVX 256b负载可以每个时钟维持2个。它还为简单的寻址模式添加了一个额外的store-AGU端口。
Haswell / Skylake的峰值吞吐量是每个时钟加载并存储96字节,但是英特尔的优化手册建议Skylake的持续平均吞吐量(仍然假设没有L1D或TLB丢失)每个周期约为81B。(根据我在SKL上的测试,一个标量整数循环可以在每个时钟上承受 2个负载+ 1个存储,从4个融合域uops中每个时钟执行7个(非融合域)uos。但是使用64位操作数而不是使用它会减慢速度32位,因此显然存在一些微体系结构资源限制,这不仅仅是将存储地址地址调度到端口2/3并从负载中窃取周期的问题。)
我们如何根据其参数计算缓存的吞吐量?
除非参数包含实际的吞吐量数字,否则您不能这样做。如上所述,即使是Skylake的L1D也无法完全满足256b向量的加载/存储执行单元的需求。尽管它很接近,并且可以用于32位整数。(加载单元的数量比缓存中读取端口的数量多是没有道理的,反之亦然。您只剩下那些永远无法充分利用的硬件。请注意,L1D可能有额外的端口来发送/接收线路到/从其他内核,以及从内核内部进行读/写。)
仅查看数据总线的宽度和时钟并不能为您提供全部信息。
L2和L3(以及内存)的带宽可能受L1或L2可以跟踪的未命中次数的限制。带宽不能超过延迟* max_concurrency,并且延迟L3较高的芯片(如多核Xeon)与相同微体系结构的双/四核CPU相比,单核L3带宽要少得多。请参阅此SO解答的“延迟绑定平台”部分。Sandybridge系列CPU具有10个行填充缓冲区以跟踪L1D丢失(也由NT商店使用)。
(在大型Xeon上,具有多个活动内核的L3 /内存总带宽巨大,但是在相同的时钟速度下,单线程代码的带宽要比四核处理器差,因为更多的内核意味着环形总线上的停止更多,因此更高延迟L3。)
缓存延迟
这样的速度怎么达到?
L1D缓存的4周期负载使用延迟非常惊人,特别是考虑到它必须以开头的寻址模式[rsi + 32]
,因此必须在它具有虚拟地址之前进行加法。然后,它必须将其转换为物理,以检查缓存标签是否匹配。
(寻址模式不是[base + 0-2047]
在Intel Sandybridge系列上花费额外的时间,因此AGU中有一个用于简单寻址模式的快捷方式(通常是指针加载的情况,在这种情况下,低负载使用延迟可能是最重要的,但通常也很常见) (请参阅英特尔的优化手册,Sandybridge第2.3.5.2节L1 DCache。)这还假定没有段覆盖,并且段基地址为0
,这是正常的。)
它还必须探查存储缓冲区,以查看它是否与任何较早的存储区重叠。即使尚未执行较早的(按程序顺序)存储地址uop,也必须弄清楚这一点,因此未知存储地址。但是大概这可能与检查L1D命中同时发生。如果事实证明不需要L1D数据,因为存储转发可以从存储缓冲区提供数据,那么这没有损失。
英特尔几乎像其他所有人一样使用VIPT(虚拟索引物理标记)缓存,使用标准技巧,使缓存足够小且具有足够高的关联性,以VIPT的速度表现得像PIPT缓存(无锯齿)(可以建立索引)与TLB虚拟->物理查询并行)。
英特尔的L1高速缓存是32kiB,8路关联的。页面大小为4kiB。这意味着“索引”位(用于选择可以缓存任何给定行的8种方式中的哪一组)都在页面偏移量以下;也就是说,这些地址位是页面的偏移量,并且在虚拟和物理地址中始终相同。
有关此内容的更多详细信息以及为何小/快速缓存有用/可行(以及与较大的慢速缓存配对使用时效果很好)的其他详细信息,请参阅我关于L1D为什么比L2D小/快的答案。
小型高速缓存可能会执行大型高速缓存中过于耗电的事情,例如与获取标签同时从集合中获取数据阵列。因此,一旦比较器找到了匹配的标签,就只需复用已经从SRAM中获取的8个64字节高速缓存行之一。
(这并不是真的那么简单:Sandybridge / Ivybridge使用具有八个16个字节块的存储体的存储L1D高速缓存。如果在不同高速缓存行中对同一存储体的两次访问尝试在同一周期中执行,则会出现高速缓存-存储体冲突。 (有8个存储体,因此这可能发生在地址间隔为128的倍数时,即2个缓存行。)
只要IvyBridge不跨越64B高速缓存行边界,它对不对齐访问也不会造成任何损失。我猜想它会根据低位地址找出要读取的存储体,并设置为获得正确的1至16字节数据而需要进行的任何移位。
在高速缓存行拆分中,它仍然只是单个uop,但是可以进行多个高速缓存访问。除4k分割外,罚款仍然很小。Skylake甚至使4k分割变得相当便宜,延迟约为11个周期,与具有复杂寻址模式的普通高速缓存行分割相同。但是4k拆分的吞吐量显着低于cl-split非拆分。
资料来源: