是否有半共享缓存之类的东西?
Is there such thing as a semi-shared cache?
我正在对缓存层次结构进行一些研究,并且遇到了共享缓存和私有缓存的概念。我可以看到缓存对特定核心(在更高级别)私有以及缓存在所有核心之间共享的示例。
是否有任何此类缓存在中间层次结构级别的特定核心子集之间共享的示例,如果没有,为什么?我的印象是,这将作为延迟和命中率之间权衡的中间地带,尽管我找不到此类结构的示例。
在多个核心之间共享中间级缓存——但少于共享最后一级缓存——不是一个常见的设计点。但是,有一些设计共享 L2 缓存,内核数量与共享 L3 缓存的数量一样多。
POWER4 和 POWER5 都在两个内核之间共享 L2 缓存,L3 也在两个内核之间共享。由于 L3 缓存数据存储在芯片外(标签在芯片上)并且每个芯片只有两个内核,这更类似于仅共享最后一级缓存。 L2 的总容量受到芯片尺寸的强烈限制,而 L3(具有片外数据)具有较高的延迟,因此共享以增加有效容量比使用片上 L3 的最新设计更具吸引力。
SPARC M7 是一个更有趣的例子。 M7 有一个 256 KiB 的 L2 数据缓存在两个内核之间共享,一个 L2 指令缓存在四个内核之间共享,L3 在四个内核之间共享(我看到的文档并不完全清楚 L3 不统一,但证据通常指向 L3对每个由四个核心组成的集群都是私有的)。由于数据 L2 仅在两个内核之间共享,这可能被视为在比 L3 更少的内核之间共享 L2,即使指令 L2 与与 L3 相同数量的内核共享也是如此。
由于 M7 内核是 8 路线程(以及只有两个宽度的乱序执行),L2 延迟不太重要(线程级并行性和指令级并行性从乱序中提取)按顺序执行可以隐藏延迟,更窄的内核可以减少给定数量的停顿周期造成的执行潜在损失)。由于该处理器针对具有高线程级并行性和低指令级并行性的商业工作负载,因此增加核心和线程数是主要目标;共享 L2 缓存可以利用共同的指令和数据使用——前者特别重要,但数据共享并不少见——有助于降低总容量,为更多内核留出空间。
SPARC M8 与此类似,但 L2 数据高速缓存设为私有,并且问题宽度加倍为四宽度。问题宽度的增加增加了 L2 延迟的重要性,尤其是对于中等大小 (16 KiB) 的 L1 缓存。考虑到在指令流中提前获取的能力,指令缓存的延迟容忍度更高。
中级缓存共享权衡的一些考虑
通过共享增加 L2 缓存的大小将在容量需求不平衡时降低容量未命中率(不仅当一个核心处于非活动状态时,甚至当同一程序的不同阶段在不同核心上处于活动状态时),但是在多个内核之间共享 L2 会增加冲突未命中率。增加关联性可以以每次访问的更高能量为代价消除这种影响。
当两个核心在较短的时间内访问相同的内存位置时,共享缓存可以通过减少复制来增加有效容量,并可能改进替换决策并提供有限的预取。共享还可以减少缓存块乒乓if writer和reader共享二级缓存;然而,明确地利用这些增加了软件核心分配的复杂性。如果共享频繁写入的值不可避免地很普遍,那么即使随机减少乒乓球也可能很有吸引力,但随着所涉及的核心数量的增加,好处会迅速减少。
当 L2 是中级缓存时,访问延迟非常重要,因为较小的 L2 的容量丢失通常会在 L3 中命中。容量翻倍将增加 40% 以上的访问延迟(延迟大致与容量的平方根成正比)。多个请求者之间的仲裁也往往会增加等待时间。 (一个非统一的缓存架构,其中不同的缓存块具有不同的延迟可以弥补这种情况。例如,在两个核心之间共享的情况下,四分之一的容量可以位于最靠近每个核心的位置,而剩下的一半位于中间与两个核心的距离。但是,NUCA 引入了分配的复杂性。)
虽然增加 L2 容量会占用 L3 缓存(或更多内核或其他功能)本来可以使用的区域,但 L3 切片的大小通常比 L2 容量大得多,因此这种影响不是主要考虑因素.
在两个核心之间共享 L2 也意味着所提供的带宽必须适合两个高度活跃的核心。虽然银行可以用来促进这种情况(并且额外的带宽可能被单个活动核心利用),但这种增加的带宽并非完全免费。
共享 L2 也会增加缓存分配和替换的复杂性。人们宁愿避免一个核心浪费容量(甚至关联性)。有时会为末级缓存提供此类调节机制(例如,Intel 的缓存分配技术),因此这不是硬性障碍。一些调节机制通常也可以促进更好的替换,L2 机制可以利用与 L3 缓存关联的元数据(减少元数据跟踪的标记开销)来调整行为。
共享 L2 缓存还引入了频率调整方面的复杂性。如果一个内核支持较低的频率,则内核与 L2 之间的接口将变得更加复杂,从而增加访问延迟。 (理论上,像上面提到的那样的 NUCA 设计可以在本地频率有一个小的接近部分 运行,并且只在访问更远的部分时支付时钟边界交叉惩罚。)
当 L2 缓存专用于单个内核时,电源门控也得到了简化。与其拥有三个电源域(两个内核和 L2),不如使用其内核关闭专用 L2,因此只需要两个电源域。 (请注意,添加电源域并不是非常昂贵,并且已被提议通过动态降低缓存容量来降低功耗。)
共享的二级缓存还可以为片上网络提供方便的合并点,减少更广泛网络中的节点数量。 (这种合并也可以在 L2 缓存后面完成,从而在两个内核之间提供更低的延迟和可能更高的带宽通信,同时还提供隔离。)
结论
从根本上说,共享提高了利用率——这有利于吞吐量(粗略地说,效率)但不利于延迟(本地性能)——但阻碍了专业化的优化。对于具有支持 L3 缓存的 L2 缓存,专业化优势(更低的延迟)往往超过通用设计的利用率优势(通常以吞吐量和效率换取更低的延迟)。片上 L3 缓存降低了 L2 容量未命中的成本,因此更高的 L2 未命中率和更快的 L2 命中时间可以减少平均内存访问时间。
以设计复杂性和一些开销为代价,可以使共享更灵活或可以降低共享成本。复杂性的增加增加了开发风险和营销风险(不仅是上市时间,而且功能复杂性增加了买方选择的难度,但营销简化似乎具有欺骗性)。对于 L2 缓存,更细微的共享成本似乎通常不值得潜在的好处。
我正在对缓存层次结构进行一些研究,并且遇到了共享缓存和私有缓存的概念。我可以看到缓存对特定核心(在更高级别)私有以及缓存在所有核心之间共享的示例。
是否有任何此类缓存在中间层次结构级别的特定核心子集之间共享的示例,如果没有,为什么?我的印象是,这将作为延迟和命中率之间权衡的中间地带,尽管我找不到此类结构的示例。
在多个核心之间共享中间级缓存——但少于共享最后一级缓存——不是一个常见的设计点。但是,有一些设计共享 L2 缓存,内核数量与共享 L3 缓存的数量一样多。
POWER4 和 POWER5 都在两个内核之间共享 L2 缓存,L3 也在两个内核之间共享。由于 L3 缓存数据存储在芯片外(标签在芯片上)并且每个芯片只有两个内核,这更类似于仅共享最后一级缓存。 L2 的总容量受到芯片尺寸的强烈限制,而 L3(具有片外数据)具有较高的延迟,因此共享以增加有效容量比使用片上 L3 的最新设计更具吸引力。
SPARC M7 是一个更有趣的例子。 M7 有一个 256 KiB 的 L2 数据缓存在两个内核之间共享,一个 L2 指令缓存在四个内核之间共享,L3 在四个内核之间共享(我看到的文档并不完全清楚 L3 不统一,但证据通常指向 L3对每个由四个核心组成的集群都是私有的)。由于数据 L2 仅在两个内核之间共享,这可能被视为在比 L3 更少的内核之间共享 L2,即使指令 L2 与与 L3 相同数量的内核共享也是如此。
由于 M7 内核是 8 路线程(以及只有两个宽度的乱序执行),L2 延迟不太重要(线程级并行性和指令级并行性从乱序中提取)按顺序执行可以隐藏延迟,更窄的内核可以减少给定数量的停顿周期造成的执行潜在损失)。由于该处理器针对具有高线程级并行性和低指令级并行性的商业工作负载,因此增加核心和线程数是主要目标;共享 L2 缓存可以利用共同的指令和数据使用——前者特别重要,但数据共享并不少见——有助于降低总容量,为更多内核留出空间。
SPARC M8 与此类似,但 L2 数据高速缓存设为私有,并且问题宽度加倍为四宽度。问题宽度的增加增加了 L2 延迟的重要性,尤其是对于中等大小 (16 KiB) 的 L1 缓存。考虑到在指令流中提前获取的能力,指令缓存的延迟容忍度更高。
中级缓存共享权衡的一些考虑
通过共享增加 L2 缓存的大小将在容量需求不平衡时降低容量未命中率(不仅当一个核心处于非活动状态时,甚至当同一程序的不同阶段在不同核心上处于活动状态时),但是在多个内核之间共享 L2 会增加冲突未命中率。增加关联性可以以每次访问的更高能量为代价消除这种影响。
当两个核心在较短的时间内访问相同的内存位置时,共享缓存可以通过减少复制来增加有效容量,并可能改进替换决策并提供有限的预取。共享还可以减少缓存块乒乓if writer和reader共享二级缓存;然而,明确地利用这些增加了软件核心分配的复杂性。如果共享频繁写入的值不可避免地很普遍,那么即使随机减少乒乓球也可能很有吸引力,但随着所涉及的核心数量的增加,好处会迅速减少。
当 L2 是中级缓存时,访问延迟非常重要,因为较小的 L2 的容量丢失通常会在 L3 中命中。容量翻倍将增加 40% 以上的访问延迟(延迟大致与容量的平方根成正比)。多个请求者之间的仲裁也往往会增加等待时间。 (一个非统一的缓存架构,其中不同的缓存块具有不同的延迟可以弥补这种情况。例如,在两个核心之间共享的情况下,四分之一的容量可以位于最靠近每个核心的位置,而剩下的一半位于中间与两个核心的距离。但是,NUCA 引入了分配的复杂性。)
虽然增加 L2 容量会占用 L3 缓存(或更多内核或其他功能)本来可以使用的区域,但 L3 切片的大小通常比 L2 容量大得多,因此这种影响不是主要考虑因素.
在两个核心之间共享 L2 也意味着所提供的带宽必须适合两个高度活跃的核心。虽然银行可以用来促进这种情况(并且额外的带宽可能被单个活动核心利用),但这种增加的带宽并非完全免费。
共享 L2 也会增加缓存分配和替换的复杂性。人们宁愿避免一个核心浪费容量(甚至关联性)。有时会为末级缓存提供此类调节机制(例如,Intel 的缓存分配技术),因此这不是硬性障碍。一些调节机制通常也可以促进更好的替换,L2 机制可以利用与 L3 缓存关联的元数据(减少元数据跟踪的标记开销)来调整行为。
共享 L2 缓存还引入了频率调整方面的复杂性。如果一个内核支持较低的频率,则内核与 L2 之间的接口将变得更加复杂,从而增加访问延迟。 (理论上,像上面提到的那样的 NUCA 设计可以在本地频率有一个小的接近部分 运行,并且只在访问更远的部分时支付时钟边界交叉惩罚。)
当 L2 缓存专用于单个内核时,电源门控也得到了简化。与其拥有三个电源域(两个内核和 L2),不如使用其内核关闭专用 L2,因此只需要两个电源域。 (请注意,添加电源域并不是非常昂贵,并且已被提议通过动态降低缓存容量来降低功耗。)
共享的二级缓存还可以为片上网络提供方便的合并点,减少更广泛网络中的节点数量。 (这种合并也可以在 L2 缓存后面完成,从而在两个内核之间提供更低的延迟和可能更高的带宽通信,同时还提供隔离。)
结论
从根本上说,共享提高了利用率——这有利于吞吐量(粗略地说,效率)但不利于延迟(本地性能)——但阻碍了专业化的优化。对于具有支持 L3 缓存的 L2 缓存,专业化优势(更低的延迟)往往超过通用设计的利用率优势(通常以吞吐量和效率换取更低的延迟)。片上 L3 缓存降低了 L2 容量未命中的成本,因此更高的 L2 未命中率和更快的 L2 命中时间可以减少平均内存访问时间。
以设计复杂性和一些开销为代价,可以使共享更灵活或可以降低共享成本。复杂性的增加增加了开发风险和营销风险(不仅是上市时间,而且功能复杂性增加了买方选择的难度,但营销简化似乎具有欺骗性)。对于 L2 缓存,更细微的共享成本似乎通常不值得潜在的好处。