理解 `_mm_prefetch`

Vla*_*ein 4 c++ performance prefetch intrinsics micro-optimization

答案_mm_prefetch() 局部性提示是什么?详细说明提示的含义。

\n

我的问题是:我想要哪一个

\n

我正在研究一个被重复调用数十亿次的函数,其中一些int参数。我做的第一件事是使用该参数(其低 32 位)作为 4GB 缓存的键来查找一些缓存值。根据调用该函数的算法,我知道该密钥通常会从一次调用到下一次调用加倍(左移 1 位),所以我这样做:

\n
int foo(int key) {\n  uint8_t value = cache[key];\n  _mm_prefetch((const char *)&cache[key * 2], _MM_HINT_T2);\n  // ...\n
Run Code Online (Sandbox Code Playgroud)\n

目标是拥有这个value在下次调用该函数时将其放入处理器缓存中。

\n

我正在寻找对我对两点的理解的确认:

\n
    \n
  1. 致电给_mm_prefetch不会延迟紧随其后的指令的处理。
  2. \n
  3. 预取错误的位置不会受到任何惩罚,只是因为猜测正确而失去了好处。
  4. \n
\n

该函数使用 128 128 位值(总共 2 KB)的查找表。有没有办法 \xe2\x80\x9cforce\xe2\x80\x9d 它被缓存?该查找表的索引按顺序递增;我也应该预取它们吗?我可能应该使用另一个提示来指向另一个级别的缓存?这里最好的策略是什么?

\n

Iod*_*Pit 5

正如我在评论中指出的,预取错误地址存在一些风险 - 有用的地址将从缓存中逐出,可能导致缓存未命中。

那是说:

_mm_prefetch编译成PREFETCHn指令。我在AMD出版的AMD64架构程序员手册中查找了指令。(请注意,所有这些信息都必须是特定于芯片组的;您可能需要查找 CPU 的文档)。

AMD 说(我的重点):

该指令的操作取决于实现。处理器实现可以忽略或更改该指令。缓存行的大小还取决于实现,最小大小为 32 字节。AMD 处理器将 PREFETCH1 和 PREFETCH2 别名为 PREFETCH0

这似乎意味着,如果您在 AMD 上运行,则该提示将被忽略,并且内存将加载到所有级别的缓存中 -除非提示它是 NTA(非临时访问) ,尝试以最小的缓存污染加载内存)。

这是说明的完整页面

预取

我认为最终的指导就是另一个答案所说的:集思广益、实施、测试和衡量。您正处于性能的最前沿,并且不会有一个一刀切的答案。

另一个可能对您有帮助的资源是Agner Fog 的优化手册,它将帮助您针对特定的 CPU 进行优化。