什么是 _mm_prefetch() 位置提示?

What are _mm_prefetch() locality hints?

intrinsics guide 关于 void _mm_prefetch (char const* p, int i) 只说了这么多:

Fetch the line of data from memory that contains address p to a location in the cache heirarchy specified by the locality hint i.

你能列出 int i 参数的可能值并解释它们的含义吗?

我找到了 _MM_HINT_T0_MM_HINT_T1_MM_HINT_T2_MM_HINT_NTA_MM_HINT_ENTA,但我不知道这是否详尽无遗列表及其含义。

如果特定于处理器,我想知道它们在 Ryzen 和最新的 Intel Core 处理器上做了什么。

有时内在函数根据它们所代表的指令而不是描述中给出的抽象语义更好地理解。


像今天一样,完整的位置常量集是

#define _MM_HINT_T0 1
#define _MM_HINT_T1 2
#define _MM_HINT_T2 3
#define _MM_HINT_NTA 0
#define _MM_HINT_ENTA 4
#define _MM_HINT_ET0 5
#define _MM_HINT_ET1 6
#define _MM_HINT_ET2 7

如所述in this paper about Intel Xeon Phi coprocessor prefetching capabilities

对于 IA32/AMD 个处理器,集合减少到

#define _MM_HINT_T0 1
#define _MM_HINT_T1 2
#define _MM_HINT_T2 3
#define _MM_HINT_NTA 0
#define _MM_HINT_ET1 6

_mm_prefetch根据体系结构和位置提示编译成不同的指令

    Hint              IA32/AMD          iMC
_MM_HINT_T0           prefetcht0     vprefetch0
_MM_HINT_T1           prefetcht1     vprefetch1
_MM_HINT_T2           prefetcht2     vprefetch2
_MM_HINT_NTA          prefetchnta    vprefetchnta
_MM_HINT_ENTA              -         vprefetchenta
_MM_HINT_ET0               -         vprefetchet0
_MM_HINT_ET1          prefetchwt1    vprefetchet1
_MM_HINT_ET2               -         vprefetchet2

如果满足所有要求,(v)prefetch 指令的作用是将缓存行的数据放入由位置提示指定的缓存级别。
该指令只是一个提示,可能会被忽略。

当一行被预取到级别 X 时,手册(Intel 和 AMD)都说它也被预取到所有其他更高级别(但对于 X=3 的情况)。
我不确定这是否真的是真的,我相信该行是预取 with-respect-to 缓存级别 X 并取决于更高级别的缓存策略(包含与非-包括)它可能也可能不存在。

(v)prefetch指令的另一个属性是非时间属性。
非时态数据不太可能很快被重用。
据我了解,对于 IA32 架构1,NT 数据存储在“流加载缓冲区”中,而对于 iMC 架构,它存储在普通缓存中(用作硬件线程的方式id) 但使用最近使用替换策略(以便在需要时它将成为下一个被逐出的行)。
对于 AMD,手动读取实际位置取决于实现,范围从软件不可见缓冲区到专用的非临时缓存。

(v)prefetch 指令的最后一个属性是“intent”属性或“eviction”属性。
由于 MESI 和变体协议,必须进行所有权请求才能使线路进入独占状态(以便对其进行修改)。
RFO 只是一个特殊的读取,所以用 RFO 预取它会直接将它带入独占状态(否则由于需要“延迟”RFO,第一次存储它会取消预取的好处),当然我们知道我们会稍后再写。

IA32 和 AMD 架构不支持和独占非时间提示(目前),因为非时间缓存级别的方式是实现定义的。
iMC 架构允许使用本地代码 _MM_HINT_ENTA.

1 我理解为 WC 缓冲区。 Peter Cordes 在 上澄清了这一点:prefetchnta 仅在预取 USWC 内存区域时使用行填充缓冲区。否则它预取到 L1


这里是对涉及的指令的描述,供参考

PREFETCHh

Fetches the line of data from memory that contains the byte specified with the source operand to a location in the cache hierarchy specified by a locality hint:

• T0(时间数据)— 将数据预取到缓存层次结构的所有级别。
• T1(与一级缓存未命中有关的时间数据)— 将数据预取到二级缓存和更高级别。
• T2(与二级缓存未命中有关的时间数据)——将数据预取到三级及更高级别的缓存中,或者 特定于实现的选择。
• NTA(与所有缓存级别相关的非时态数据)——将数据预取到非时态缓存结构中并 放入靠近处理器的位置,最大限度地减少缓存污染。

PREFETCHWT1

Fetches the line of data from memory that contains the byte specified with the source operand to a location in the cache hierarchy specified by an intent to write hint (so that data is brought into ‘Exclusive’ state via a request for ownership) and a locality hint:

• T1 (temporal data with respect to first level cache)—prefetch data into the second level cache.

VPREFETCHh

                 Cache  Temporal    Exclusive state
                 Level
VPREFETCH0       L1     NO          NO
VPREFETCHNTA     L1     YES         NO
VPREFETCH1       L2     NO          NO
VPREFETCH2       L2     YES         NO
VPREFETCHE0      L1     NO          YES
VPREFETCHENTA    L1     YES         YES
VPREFETCHE1      L2     NO          YES
VPREFETCHE2      L2     YES         YES