c++ - 什么是 _mm_prefetch() 位置提示?

标签 c++ x86-64 intrinsics cpu-cache prefetch

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 >,但我不知道这是否是一个详尽的列表以及它们的含义。

如果是特定于处理器的,我想知道他们在锐龙和最新的英特尔酷睿处理器上做了什么。

最佳答案

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


与今天一样,完整的位置常数集是

#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-and-variant 协议(protocol),必须提出所有权请求以使线路进入独占状态(以便对其进行修改)。
RFO 只是一种特殊的读取,因此使用 RFO 预取它会直接将它带入 Exclusive 状态(否则,由于需要“延迟”RFO,第一次存储将取消预取的好处),当然我们知道我们会稍后再写。

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

1 我理解为 WC 缓冲区。 Peter Cordes 在 comment below 上澄清了这一点。 : prefetchnta 仅在预取 USWC 内存区域时使用 Line-Fill 缓冲区。否则它会预取到 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

关于c++ - 什么是 _mm_prefetch() 位置提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46521694/

相关文章:

c++ - _mm_moveh_ps 的 AVX 等效项

c++ - 内存使用比较

c++ - 有没有办法列出所有共享内存对象的名称?

c++ - 如何在输出参数中使用基类

llvm - 将 LLVM IR 分析与最终地址关联起来

c - 2 个 AVX-512 vector 元素的交错合并 - C 内在函数

performance - cuda内在函数sqrtf和powf性能问题

c++ - 为什么 MSVC++ 认为 "std::strcat"是 "unsafe"? (C++)

matplotlib - .plt .plt.got 有什么不同?

assembly - 在 x86-32 处理器上运行 x86-64 ASM