我可以在 Java 代码中做什么来优化 CPU 缓存? [英] What can I do in Java code to optimize for CPU caching?

查看:26
本文介绍了我可以在 Java 代码中做什么来优化 CPU 缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写 Java 程序时,我是否会影响 CPU 将如何利用其缓存来存储我的数据?例如,如果我有一个经常被访问的数组,如果它足够小以适合一个缓存行(在 64 位机器上通常为 128 字节)是否有帮助?如果我将一个经常使用的对象保留在该限制内,我是否可以期望它的成员使用的内存靠近在一起并留在缓存中?

When writing a Java program, do I have influence on how the CPU will utilize its cache to store my data? For example, if I have an array that is accessed a lot, does it help if it's small enough to fit in one cache line (typically 128 byte on a 64-bit machine)? What if I keep a much used object within that limit, can I expect the memory used by it's members to be close together and staying in cache?

背景:我正在构建一个压缩的数字树,它深受Judy 数组,使用 C 语言编写.虽然我主要使用它的节点压缩技术,但 Judy 有 CPU 缓存优化作为中心设计目标,节点类型以及在它们之间切换的启发式方法都受此影响.我想知道我是否也有机会获得这些好处?

Background: I'm building a compressed digital tree, that's heavily inspired by the Judy arrays, which are in C. While I'm mostly after its node compression techniques, Judy has CPU cache optimization as a central design goal and the node types as well as the heuristics for switching between them are heavily influenced by that. I was wondering if I have any chance of getting those benefits, too?

编辑:到目前为止答案的一般建议是,当您离机器太远时,不要尝试对机器级别的细节进行微优化爪哇.我完全同意,所以觉得我必须添加一些(希望)澄清评论,以更好地解释为什么我认为这个问题仍然有意义.它们如下:

由于计算机的构建方式,有些事情通常更容易让计算机处理.我已经看到 Java 代码在压缩数据(来自内存)上的运行速度明显更快,即使解压缩必须使用额外的 CPU 周期.如果数据存储在磁盘上,原因很明显,但当然在 RAM 中,原理是相同的.

There are some things that are just generally easier for computers to handle because of the way they are built. I have seen Java code run noticeably faster on compressed data (from memory), even though the decompression had to use additional CPU cycles. If the data were stored on disk, it's obvious why that is so, but of course in RAM it's the same principle.

现在,计算机科学有很多关于这些东西的说法,例如,引用局部性在 C 中很好,我想它在 Java 中仍然很好,如果它有助于优化运行时做更多事情,也许更是如此聪明的东西.但是你如何完成它可能会有很大的不同.在 C 中,我可能会编写代码来管理更大的内存块,并使用相邻的指针来处理相关数据.

Now, computer science has lots to say about what those things are, for example, locality of reference is great in C and I guess it's still great in Java, maybe even more so, if it helps the optimizing runtime to do more clever things. But how you accomplish it might be very different. In C, I might write code that manages larger chunks of memory itself and uses adjacent pointers for related data.

在 Java 中,我不能(也不想)了解特定运行时将如何管理内存.因此,我也必须将优化提升到更高的抽象级别.我的问题基本上是,我该怎么做?对于引用的局部性,在我正在使用 Java 进行的抽象级别上,靠近在一起"是什么意思?同一个对象?同类型?同一个数组?

In Java, I can't (and don't want to) know much about how memory is going to be managed by a particular runtime. So I have to take optimizations to a higher level of abstraction, too. My question is basically, how do I do that? For locality of reference, what does "close together" mean at the level of abstraction I'm working on in Java? Same object? Same type? Same array?

总的来说,我不认为抽象层会改变物理定律",从比喻的角度来说.每次用完空间时将数组的大小加倍也是 Java 中的一个好策略,即使您不再调用 malloc().

In general, I don't think that abstraction layers change the "laws of physics", metaphorically speaking. Doubling your array in size every time you run out of space is a good strategy in Java, too, even though you don't call malloc() anymore.

推荐答案

使用 Java 获得良好性能的关键是编写惯用的代码,而不是试图以智取胜 JIT 编译器.如果您编写代码以试图影响它在本机指令级别以某种方式做事,您更有可能在脚下开枪.

The key to good performance with Java is to write idiomatic code, rather than trying to outwit the JIT compiler. If you write your code to try to influence it to do things in a certain way at the native instruction level, you are more likely to shoot yourself in the foot.

这并不是说参考位置等通用原则无关紧要.他们这样做,但我认为使用数组等是性能感知、惯用代码,但不是棘手".

That isn't to say that common principles like locality of reference don't matter. They do, but I would consider the use of arrays and such to be performance-aware, idiomatic code, but not "tricky."

HotSpot 和其他优化运行时在如何为特定处理器优化代码方面非常聪明.(例如,查看此讨论.) 如果我是专家级机器语言程序员,我会编写机器语言,而不是 Java.如果我不是,那么认为我可以比专家更好地优化代码是不明智的.

HotSpot and other optimizing runtimes are extremely clever about how they optimize code for specific processors. (For an example, check out this discussion.) If I were an expert machine language programmer, I'd write machine language, not Java. And if I'm not, it would be unwise to think that I could do a better job of optimizing my code than the experts.

此外,即使您确实知道为特定 CPU 实现某些东西的最佳方法,Java 的美妙之处在于一次编写,随处运行.优化"Java 代码的巧妙技巧往往会使 JIT 更难识别优化机会.遵循常见习惯用法的直接代码更容易被优化器识别.因此,即使您为测试平台获得了最好的 Java 代码,该代码在不同的架构上也可能表现得很糟糕,或者充其量无法利用未来 JIT 中的增强功能.

Also, even if you do know the best way to implement something for a particular CPU, the beauty of Java is write-once-run-anywhere. Clever tricks to "optimize" Java code tend to make optimization opportunities harder for the JIT to recognize. Straight-forward code that adheres to common idioms is easier for an optimizer to recognize. So even when you get the best Java code for your testbed, that code might perform horribly on a different architecture, or at best, fail to take advantages of enhancements in future JITs.

如果您想要良好的性能,请保持简单.由非常聪明的人组成的团队正在努力加快速度.

If you want good performance, keep it simple. Teams of really smart people are working to make it fast.

这篇关于我可以在 Java 代码中做什么来优化 CPU 缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆