DCU预取器在哪种情况下开始预取?

时间:2018-11-28 10:47:34

标签: x86 intel cpu-architecture cpu-cache prefetch

我正在阅读有关Intel Core i7系统中可用的不同预取器的信息。 我进行了实验,以了解何时调用这些预取器。

这些是我的发现

  1. L1 IP预取器在3次高速缓存未命中后开始预取。它只是 预取缓存命中。

  2. L2相​​邻行预取器在第一次高速缓存未命中后开始预取 并预取缓存未命中。

  3. L2 H / W(跨步)预取器在第一次高速缓存未命中后开始预取 并预取缓存命中率。

我无法理解DCU预取器的行为。它何时开始预取或调用?是否在缓存命中或未命中时预取下一个缓存行?

我已经浏览了英特尔文档disclosure-of-hw-prefetcher,在该文档中提到-DCU预取器将下一个高速缓存行提取到L1-D高速缓存中,但是在开始预取时没有明确的信息。

有人可以解释DCU预取器何时开始预取吗?

2 个答案:

答案 0 :(得分:4)

DCU预取器未以确定性方式预取行。它似乎具有与每个潜在的预取请求关联的置信度值。如果置信度仅大于某个阈值,则将触发预取。而且,似乎如果两个L1预取器都启用,则它们中只有一个可以在同一周期内发出预取请求。也许可以接受较高信任度的预取。下面的答案没有考虑这些观察结果。 (需要做更多的实验工作。以后我会重写它。)


英特尔手册向我们介绍了有关DCU预取器的一些信息。优化手册的第2.4.5.4节和第2.5.4.2节都说如下:

  

数据缓存单元(DCU)预取器-此预取器,也称为   流式预取器,是由对   最近加载的数据。处理器假定此访问权限是其中的一部分   流算法,并自动获取下一行。

请注意,第2.4.5.4节是Sandy Bridge的一部分,而第2.5.4.2节是Intel Core的一部分。 DCU预取程序首先在Intel Core微体系结构上受支持,并且在以后的所有微体系结构中也受支持。据我所知,没有迹象表明DCU预取器已经随着时间而改变。因此,我认为至少在所有直到Skylake的微体系结构上它都完全一样。

那句话并没有说太多。 “升序访问”部分建议预取器由偏移量增加的多次访问触发。 “最近加载的数据”部分含糊不清。它可能指的是紧接在地址空间中要预取的行之前的一个或多个行。还不清楚这是指虚拟地址还是物理地址。 “获取下一行”部分表明,每次触发时,它仅获取一行,并且该行是触发预取的行的后一行。

我已经在Haswell上进行了一些实验,除了DCU预取器之外,所有预取器都被禁用。我还禁用了超线程。这使我能够独立研究DCU预取器。结果显示如下:

  • DCU预取器最多可以跟踪4个不同的4KB(可能是物理)页面的访问。
  • 当在同一缓存集中中的一个或多个行有三个或更多访问时,DCU预取程序将触发。访问必须是需求加载或软件预取(包括prefetchnta的任何预取指令)或两者的组合。访问可以是L1D中的命中或未命中,或者是两者的组合。触发后,对于当前正在跟踪的4个页面,它将在相应页面的 each 中预取下一行。例如,请考虑以下三个需求负载缺失:0xF1000、0xF2008和0xF3004。假设要跟踪的4个页面是0xF1000、0xF2000、0xF3000和0xF4000。然后,DCU预取器将预取以下行:0xF1040、0xF2040、0xF3040和0xF4040。
  • 当在两个连续的高速缓存集中的一个或多个行中有三个或三个以上的访问权限时,会触发DCU预取器。像以前一样,访问必须是需求负载或软件预取。访问可以是L1D中的命中或未命中。触发后,对于当前正在跟踪的4个页面,它将相对于具有较小物理地址的已访问缓存集预取相应页面的 each 中的下一行。例如,请考虑以下三个需求负载缺失:0xF1040、0xF2048和0xF3004。假设要跟踪的4个页面是0xF1000、0xF2000、0xF3000和0xF4000。然后,DCU预取器将预取以下行:0xF3040和0xF4040。不需要预取0xF1040或0xF2040,因为已经有请求。
  • 预取器将不会预取到下一个4KB页面。因此,如果这三个访问是对页面最后一行的访问,则不会触发预取器。
  • 要跟踪的页面如下选择。每当需求负载或软件预取访问页面时,都会跟踪该页面,它将替换当前正在跟踪的4个页面之一。我没有进一步研究用于确定要替换4页中的哪一页的算法。不过,这可能很简单。
  • 如果由于访问前一个项目符号中提到的类型而导致跟踪新页面,则至少需要再两次访问同一页面和同一行,才能触发预取器进行预取下一行。否则,如果L1中尚不存在对下一行的后续访问,则会丢失该行。之后,无论哪种方式,DCU预取器的行为都如第二和第三项目要点所述。例如,请考虑以下三个需求负载缺失:0xF1040、0xF2048和0xF3004。对同一行有两次访问,第三个访问相同的缓存集,但访问的行不同。这些访问将使DCU预取器跟踪两个页面,但不会立即触发它。当预取程序看到对同一缓存集中的任何一行的另外三个访问时,它将为当前正在跟踪的那些页面预取下一行。作为另一个示例,请考虑以下三个需求负载丢失:0xF1040、0xF2048和0xF3030。这些访问都在同一行上,因此它们不仅使预取器跟踪该页面,而且还会触发该页面以及已被跟踪的任何其他页面的下一行预取。
  • 在我看来,预取器正在从正在访问的页面(从TLB)的页面表条目中接收到脏标志。该标志指示页面是否脏。如果脏了,则预取器将不会跟踪页面,并且对该页面的访问将不计入满足触发条件的三个访问中。因此,似乎DCU预取器只是忽略脏页。就是说,尽管预取器支持该页面,但该页面不必是只读的。但是,需要进行更彻底的调查才能更准确地了解商店如何与DCU预取器进行交互。

因此,触发预取器的访问不必“升序”或遵循任何顺序。高速缓存行偏移量本身似乎被预取器忽略。仅物理页码很重要。

我认为DCU预取器具有一个包含4个条目的完全关联缓冲区。每个条目都标记有(可能是物理的)页码,并具有一个有效位来指示该条目是否包含有效的页码。另外,L1D的每个高速缓存集都与一个2位饱和计数器关联,每当需求负载或软件预取请求访问相应的高速缓存集并且未设置访问页面的脏标志时,该计数器就会递增。当计数器的值达到3时,将触发预取器。预取器已经具有需要从中进行预取的物理页码。它可以从与计数器相对应的缓冲区条目中获取它们。因此,它可以立即为缓冲区所跟踪的每个页面的下一个缓存行发出预取请求。但是,如果填充缓冲区不可用于触发的预取请求,则将删除预取。然后计数器将重置为零。页表可能会被修改。每当刷新TLB时,预取器就有可能刷新其缓冲区。

可能存在两个DCU预取器,每个逻辑核一个。禁用超线程时,也会禁用其中一个预取器。也可能是包含页码的4个缓冲区条目在两个逻辑核心之间静态分区,并且在禁用超线程时组合在一起。我不确定,但是这种设计对我来说很有意义。另一种可能的设计是每个预取器都有一个专用的4入口缓冲区。启用超线程后,不难确定DCU预取器的工作方式。我只是没有花精力去研究它。

总而言之,DCU pefetcher是迄今为止在现代高性能Intel处理器中可用的4种数据预取器中最简单的。似乎仅当顺序但缓慢地访问小块只读数据(例如只读文件和静态初始化的全局数组)或同时访问可能包含许多小字段的多个只读对象时,此方法才有效并跨越同一页面中的几个连续的缓存行。

第2.4.5.4节还提供了有关L1D预取的其他一般信息,因此适用于DCU预取器。

  

在以下情况下,数据预取是由装入操作触发的   满足条件:

     
      
  • 加载来自回写内存类型。
  •   

这意味着DCU预取器将不会跟踪对WP和WT可缓存内存类型的访问。

  
      
  • 预取的数据与触发它的加载指令在同一4K字节页内。
  •   

这已通过实验验证。

  
      
  • 管道中没有围栏。
  •   

我不知道这意味着什么。参见:https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/805373

  
      
  • 没有其他许多未命中的负载。
  •   

只有10个填充缓冲区可以容纳未命中L1D的请求。这提出了一个问题,尽管如果只有一个可用的填充缓冲区,硬件预取器将使用它还是将其留给预期的需求访问?我不知道。

  
      
  • 没有连续的商店。
  •   

这表明,如果有大量商店相互缠绕而负载很少,那么L1预取器将忽略这些负载并基本上暂时关闭,直到商店变成少数。但是,我的实验结果表明,即使将单个商店存储到页面上,也会关闭该页面的预取器。

所有Intel Atom微体系结构均具有DCU预取器。尽管预取程序在这些微体系结构中可能跟踪不到4页。

所有Xeon Phi微体系结构(包括Knights Landing在内)都没有DCU预取器。我不知道后来的Xeon Phi微体系结构。

答案 1 :(得分:0)

AFAIK,Intel CPU没有L1相邻行预取器。

它在L2中有一个,它试图完成一对128字节对齐的64字节高速缓存行。 (因此不一定是下一行,如果导致某行被缓存的需求缺失或其他预取是一对中的上半部,则可能是前一行。

另请参阅https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/714832,以及SO上的许多“相关”链接,例如prefetching data at L1 and L2。尽管不确定https://software.intel.com/en-us/articles/intel-sdm#optimization

中的哪一个是否比英特尔优化手册的“预取”部分更多的信息。

我不确定在只有一对线路中的一条线路时,是否有任何试探来避免浪费带宽和缓存占用空间,而不是在有足够的未命中需求时不进行预取。