对于超快速代码,至关重要的一点是,我们必须保持引用的局部性-将尽可能多的紧密使用的数据保留在CPU缓存中:

http://en.wikipedia.org/wiki/Locality_of_reference

有什么技术可以做到这一点?人们能举个例子吗?

我对Java和C/C++示例感兴趣。有趣的是人们停止大量缓存交换的方式。

问候

最佳答案

这可能太笼统而无法给出明确的答案。与Java相比,C或C++中的方法会有很大的不同(语言对对象进行布局的方式有所不同)。

最基本的是,将要在闭环中访问的数据保持在一起。如果您的循环在类型T上运行,并且具有成员m1 ... mN,但在关键路径中仅使用m1 ... m4,请考虑将T分为包含m1 ... m4的T1和包含m4的T2。 ..mN。您可能想要向T1添加指向T2的指针。尝试避免相对于缓存边界未对齐的对象(取决于平台)。

使用连续的容器(在C中为纯旧数组,在C++中为vector),并尝试管理迭代的向上或向下,但不要在容器上随机跳转。链接列表是本地性的杀手,列表中的两个连续节点可能位于完全不同的随机位置。

Java中的对象容器(和泛型)也是杀手er,而在Vector中,引用是连续的,而实际对象则不是(存在额外的间接级别)。在Java中,有很多额外的变量(如果您用new一个对象一个接一个地紧接两个对象,那么即使有一些额外的信息(通常是两个或三个指针),这些对象也可能最终位于几乎连续的内存位置介于两者之间的对象管理数据。GC会移动对象,但希望不会使事情变得比运行前更糟。

如果您专注于Java,请创建紧凑的数据结构,如果您的对象具有一定的位置并且需要紧密循环访问,请考虑在对象内保留xy基本类型,而不要创建Point和持有对它的引用。引用类型需要更新,这意味着需要进行不同的分配,额外的间接访问和较少的局部性。

关于java - 将数据保存在缓存中的技术是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9821720/

10-13 07:00
查看更多