在设计java类时,建议如何实现CPU缓存友好性?
到目前为止,我学到的是,应该尽可能多地使用POD (即int而不是整数)。因此,在分配包含的对象时,将连续地分配数据。例如。
class Local
{
private int data0;
private int data1;
// ...
};比缓存更友好
class NoSoLocal
{
private Integer data0;
private Integer data1;
//...
};后者将需要为Integer对象分配两个单独的分配,这些对象可以位于内存中的任意位置,尤其是内存中的任意位置。在GC运行之后。OTOH第一种方法在数据可重用的情况下可能导致数据重复。
是否有一种方法可以使它们在内存中彼此靠近,以便父对象及其“包含元素”将同时位于CPU缓存中,而不是任意分布在整个内存中,再加上GC将它们放在一起?
发布于 2014-06-23 13:36:10
第一种方法可能导致重复使用数据的情况。
但在你提到的情况下。一个int是4个字节,引用通常是4个字节,所以您不能通过使用Integer获得任何信息。然而,对于一个更复杂的类型,它可以产生很大的不同。
是否有一种方法可以使它们在内存中彼此靠近,以便父对象及其“包含元素”将同时位于CPU缓存中,而不是任意分布在整个内存中,再加上GC将它们放在一起?
无论如何,GC都会这样做,只要对象只在一个地方使用。如果在多个地方使用对象,它们将接近一个引用。
注意:这并不一定是这样的,但是当分配对象时,它们通常是连续的,因为这是最简单的分配策略。当复制保留的对象时,HotSpot GC将以相反的发现顺序复制它们。也就是说,他们仍然在一起,但顺序相反。
注2:对于一个int使用4个字节仍然比对一个整数使用28个字节更有效(引用4个字节,对象头16个字节,值4个字节,填充4个字节)。
注3:最重要的是,与性能相比,您应该更倾向于清晰,除非您已经度量了您的需求,并且有了更好的解决方案。在这种情况下,int不能是null,但是integer可以是null。如果您想要一个不应该是null的值,请使用int,这不是为了性能,而是为了清晰。
发布于 2014-06-23 21:44:18
您不能强迫JVM将相关的对象放置在彼此之间(尽管JVM试图自动这样做)。但是,有一些技巧可以使Java程序更易于缓存。
让我给你们看看现实项目中的一些例子。
小心!--这不是用编写代码的推荐方法!
除非你完全确定你为什么要这么做,否则不要采用以下技术。
Striped64类。byte[]表示。之前的守则:
类Blob {长偏移量;int长度;byte[] sha1_hash;}
以下代码之后的代码:
类Blob {长偏移;int长度;int hash0,hash1,hash2,hash3,hash4;}String替换为char[]。您知道,Java中的String在遮罩下包含char[]对象。为什么要为额外的推荐信支付性能罚款?LinkedList通常可以被ArrayList取代。经典的HashMap可能会被打开地址哈希表所取代。https://stackoverflow.com/questions/24366785
复制相似问题