首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在加载数字流时避免缓存污染

在加载数字流时避免缓存污染
EN

Stack Overflow用户
提问于 2016-06-18 08:45:58
回答 1查看 579关注 0票数 9

在x86处理器上,是否有一种方法可以在不经过缓存层次结构的情况下将数据从常规的写回内存加载到寄存器中?

我的用例是我有一个很大的查找结构(哈希映射或B树)。我正在处理大量的数字(比我的L3大得多,但适合记忆)。我想做的事情很简单:

代码语言:javascript
复制
 int result = 0;
 for (num : stream_numbers) {
     int lookup_result = lookup_using_b_tree(num);
     result += do_some_math_that_touches_registers_only(lookup_result);
 }
 return result;

因为我只访问了每个数字一次,而且所有数字的总和超过了L3大小,我设想它们最终会驱逐一些缓存行,这些缓存行保存了B树的部分内容。相反,理想情况下,我不希望从这个流访问缓存中有任何数字,因为它们根本没有时间局部性(只读取一次)。这样,我就可以最大限度地提高B树保持缓存和查找速度的可能性。

我已经查看了SSE4.1中用于时态加载的(v)movntdqa指令。这似乎不是一个很好的适合,因为它似乎只适用于无法实现的写入组合内存。英特尔的这位老文章声称:

未来几代英特尔处理器可能包含流负载的优化和增强,例如增加流负载缓冲区的利用率和对额外内存类型的支持,从而为软件开发人员提供更多的机会来提高其应用程序的性能和能效。

然而,我不知道今天有任何这样的处理器。我读过其他地方,一个处理器可以选择忽略这个写内存的提示,而使用movdqa。那么,我是否可以在x86处理器上不经过缓存层次结构就从常规写回内存中获得负载,即使这只在Haswell和以后的模型上是可能的?我也希望能提供任何信息,如果这将是可能的未来?

EN

回答 1

Stack Overflow用户

发布于 2016-08-25 20:50:12

是的,您可以使用MOVNTI将值直接存储到内存中,而不需要它们接触缓存。

MOVNTI的延迟时间约为400个周期(在Skylake上)。

但是,如果您只是存储值,那么您不关心延迟,而更关心的是交互吞吐量,即每MOVNTI一个周期。

注意,您需要在完成存储后执行SFENCE或MFENCE。

根据我对MOVNTI的实验(在ZeroMem例程的上下文中),如果您正在编写超过512KB的代码,这是值得的。

确切的值将主要取决于缓存的大小等。

非时间性只适用于,而不适用于读取!

事实上,我不知道任何non变体在读取数据时是以非时态方式工作的。

但是,如果您正在执行读-修改-写入循环,那么使用非时态移动就没有什么意义了。

您还需要考虑到节点结构的位置。

看起来很可能是这样的:

代码语言:javascript
复制
left, right: pointer_to_node  (8 bytes aligned on 32 byte boundary).
data: integer;                (4 bytes) 
....

如果是这样的话,那么读取left/right节点指针将把data沿32字节(*)缓存行吸收。

在这里,仅仅对数据执行NT-mov并没有帮助,在读取其他节点数据时,它已经被吸进去,因此已经在缓存中了。

编译器在缓存友好边界上对数据结构进行调整,可以确保每个节点指针访问都能将最大数量的节点数据隐藏到缓存中。

(*)缓存行大小取决于处理器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37895040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档