我想知道是否有办法直接管理内存的哪些部分被加载到缓存中(并保存在中)。我知道gcc中有__builtin_prefetch(),但我需要更多(至少我想我会......)。
这是我的问题: 我有一个循环,我更新矢量v(非常伪代码):
while (1) {
update_an_entry_in_v;
}
v的长度是数百万。循环运行数百万次,并且它在v中跳转。因此我的缓存命中率非常差,并且无法将所有v都放入L1缓存中。
我可以像这样重新组织代码:
for (i=0; i < length_of_v; i+=1024) {
while (1) {
update_an_entry_in_v[i:i+1023];
}
}
也就是说,首先只使用我知道的那些更新,只更新v [0:1023]中的条目,处理所有这些,然后转到下一个块,等等。
现在这可能会有更好的缓存行为,但我想知道是否有可能让它变得更好。让我们关注v [0:1023]块。我仍然会在v [0:1023]内跳转,所以硬件可能认为不再需要在L1缓存中保留那部分内存,然后,繁荣!我再次回到那个块
所以问题变成:有没有办法标记整个v [0:1023],以便在内部while循环之前将其加载到L1中,然后&#34; unmark&#34;一旦while循环结束了吗?
(显然,1024只是一个应该调整的方便的数字。使用双倍的8K内存,并且鉴于目前大多数机器至少有32-64K的L1数据缓存,应该留下足够的其他内容。)
答案 0 :(得分:1)
显然我不知道你在做什么,这有点避开了这个问题,但是如果你知道这些指标你可以对这些指标进行基数排序,然后按顺序运行整个事情,这将是高效缓存吗?也许命令他们更新了问题,但是从重新组织我猜测的代码的评论,关于它没有的机会,我会提到它。 [好吧,由于基数排序是稳定的,但是只有当它是相同的索引时,顺序才会保留这样做。