Intel Sandy Bridge/Ivy Bridge架构/微架构/流水线 (18) - 数据预取

版权声明:转载必须保留原出处,没有书面许可不可用于商用目的, https://blog.csdn.net/qq_43401808/article/details/85998354

Data Prefetching

使用软件预取指令,硬件预取机制,或者两者的任意组合,都可以将数据投机式地加载到L1D中。

程序员可以使用4条SSE预取指令来实施软件控制的预取操作。这些指令给处理器提供一些“提示”,请求将数据行加载到指定的某级缓存中。注意:软件控制的预取是针对数据的,不要预取代码。

接下来讲述Sandy Bridge提供的各种的硬件预取机制以及与前代微架构相比所作的增强点。数据预取器的设计目标是自动地预测程序即将要消费的数据。如果数据尚未在执行核中或者内层缓存(注:指处理器核中的L1和L2缓存)中,预取器会将数据从外层缓存(注:即L3/LLC缓存)或者存储器中预取到内层缓存里。预取具有如下的效果(未必都是好的):

  • 对于顺序使用数据的代码,提供程序性能。
  • 如果数据访问模式是离散的而非局部的,可能会由于带宽问题导致程序性能略微下降

注:数据预取操作会消耗部分带宽;预取的数据可能未被使用

  • 在某些罕见的情况下,如果程序的算法被调优成了占据大部分的高速缓存空间,不必要的数据预取则可能导致程序还要使用的缓存行被驱逐(evict)。考虑到L1有限的容量,硬件预取器可能会导致严重的性能恶化。

注:此时可以从BIOS设定中禁用相关的预取选项。

Data Prefetch to L1 Data Cache

当满足如下条件时,数据预取由读存操作触发:

  • 从回写式内存类型中读数据
  • 要预取的数据与触发预取的读操作读取的数据位于同一个4K页面中。

注:即不能跨页面预取数据。在Ivy Bridge微架构中有一个下页预取器(NPP,next-page prefetcher)用于跨页面进行数据预取。

  • 流水线中没有fence。(todo:解释fence)
  • 没有太多的读存未中事件在处理

注:此时不进行预取是想要节省访存带宽用于处理缓存未中事件。

  • 没有持续的写存指令流

注:节省访存带宽

有两个硬件预取器用于将数据加载到L1D缓存中:

  • DCU(data cache unit)预取器。这个预取器也被称为流式预取器(streaming prefetcher)。如果最近的读操作按地址升序模式访问存储器,则会触发DCU预取。处理器会假设这是一种流式访问算法,自动地预取下一行。
  • 基于指令指针IP的步进预取器(IP-based stride prefetcher)。这个预取器跟踪单条读存指令。如果侦测到读操作有固定的有规律的步长,则以当前地址加上步长为源地址预取下一个数据行。预取器可以侦测前向(地址升序)或者后向(地址降序)的访存模式,可以侦测的步长最长可达2K字节。

Data Prefetch to L2 and Last Level Cache

有两个硬件预取器可以将数据从存储器中预取到L2缓存和LLC缓存中:

  • 空间预取器(spatial prefetcher:对于每个读取到L2缓存中的数据行(64字节),这个预取器努力预取相邻的缓存行,从而形成一对完整的按照128字节对齐的缓存行块(即两个缓存行组合在一起按照128字节对齐)。
  • 二级流预取器(Streamer:这个预取器监视来自于L1缓存的读存请求,可以监视升序地址或者降序地址模式。受监视的读存请求包括:由读存或写存操作发起的或者由硬件预取器发起的L1D请求,以及L1I发起的取指请求。预取的缓存行必须位于同一个4K字节页面中。

这两个预取器将数据预取到LLC中。除非L2缓存已经负担着很重的未命中(注:指L1未命中?)处理请求,通常数据也会被预取到L2中。

对二级流预取器Streamer的增强如下:

  • 对每次L2查询,Streamer可以发起两个预取请求,在实际读存操作之前,最远可以提前预取20个缓存行。
  • 根据每个处理器核的未完成请求的数量动态调整预取行为。如果没有太多的未完成请求在排队,streamer可以尽可能远地进行预取。如果请求很多,则只预取到LLC且预取地比较近。
  • 当预取的缓存行比较远时,只加载到LLC缓存,但不存储到L2缓存。这种方式可以避免将L2缓冲中还会被使用的数据行替换掉。
  • 侦测并维护最多达32个数据访问流。对每个4K页面,可以维护一个前向流与一个后向流。

猜你喜欢

转载自blog.csdn.net/qq_43401808/article/details/85998354