预取()本地提示?的回答详细介绍了这个提示的含义。
我的问题是:想要哪一个?
我处理一个反复调用的函数,这个函数多次调用数十亿次,其中包括一些int参数。我做的第一件事是使用该参数(其低32位)查找一些缓存值,作为4GB缓存中的密钥。根据调用此函数的算法,我知道该键通常会加倍(左移1位)从一个调用到下一个调用,因此我正在这样做:
int foo(int key) {
uint8_t value = cache[key];
_mm_prefetch((const char *)&cache[key * 2], _MM_HINT_T2);
// ...目标是在下一次调用此函数之前将该value保存在处理器缓存中。
我想确认我对以下两点的理解:
_mm_prefetch的调用不会延迟紧接它之后的指令的处理。该函数使用128位值的查找表(总计2KB).有没有办法“强迫”它被缓存?该查找表中的索引是按顺序递增的;是否也要预取它们?我可能应该使用另一个提示,指向另一个级别的缓存?这里最好的策略是什么?
发布于 2021-01-06 23:07:45
如果你做任何与性能有关的事情,最好的和最终的方法是去尝试它。幸运的是,你完全知道该尝试什么,而且只有几种可能性。
关于你的理解-是的,这是正确的。但是,任何事情都是有代价的(例如,如果在代码中添加任何指令,处理器将浪费一纳秒来执行它)。您应该通过测量前后的性能来验证预取的想法。对于非常不规则的访问模式,它很可能起作用。
关于预取任何顺序数据,您可能不应该麻烦。缓存将数据保存在64字节的粒度,因此对于顺序数据,预取通常不会有帮助。此外,一些(全部?)缓存具有预见性加载--即使没有被告知,它们也会提前提取。
发布于 2021-01-06 23:33:59
正如我在注释中所指出的,预取错误地址有一定的风险--一个有用的地址将从缓存中被逐出,可能会导致缓存丢失。
尽管如此:
_mm_prefetch编译成PREFETCHn指令。我在AMD出版的AMD64架构程序员手册中查了一下说明书。(请注意,所有这些信息都必须是特定于芯片组的;您可能需要找到CPU的文档)。
AMD说(我强调):
该指令的操作依赖于实现.处理器实现可以忽略或更改此指令。缓存行的大小也取决于实现,最小大小为32个字节。AMD处理器别名PREFETCH1和PREFETCH2到PREFETCH0
这似乎意味着,如果您在AMD上运行,那么提示将被忽略,内存被加载到缓存的所有级别--除非它暗示它是NTA (非时态访问,试图以最小的缓存污染加载内存)。
这是说明书的全文

我认为,最终,指导是另一个答案:头脑风暴,实施,测试和测量。你正处于perf的边缘,不会有一个一刀切的答案。
另一个可能帮助您的资源是阿格纳雾优化手册,它将帮助您优化特定的CPU。
https://stackoverflow.com/questions/65604355
复制相似问题