- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在编写 Java 程序时,我是否会影响 CPU 如何利用其缓存来存储我的数据?例如,如果我有一个经常被访问的数组,如果它足够小以适合一个高速缓存行(通常在 64 位机器上为 128 字节)是否有帮助?如果我将一个经常使用的对象保持在该限制内,我可以期望它的成员使用的内存靠近在一起并保留在缓存中吗?
背景:我正在构建一个压缩的 digital tree ,这深受 Judy arrays 的启发。 ,在 C 语言中。虽然我主要关注它的节点压缩技术,但 Judy 将 CPU 缓存优化作为中心设计目标,节点类型以及在它们之间切换的启发式方法都受此影响很大。我想知道我是否也有机会获得这些好处?
编辑:到目前为止,答案的一般建议是,当您离机器如此之远时,不要尝试微优化机器级细节 java 。我完全同意,所以觉得我必须添加一些(希望)澄清评论,以更好地解释为什么我认为这个问题仍然有意义。这些如下:
由于计算机的构建方式,有些事情通常更容易处理。我已经看到 Java 代码在压缩数据(来自内存)上运行速度明显更快,即使解压缩必须使用额外的 CPU 周期。如果数据存储在磁盘上,原因很明显,但在 RAM 中当然是相同的原理。
现在,计算机科学对这些东西有很多话要说,例如,引用局部性在 C 中很棒,我想它在 Java 中仍然很棒,如果它有助于优化运行时做更多事情,也许更是如此聪明的东西。但是你如何完成它可能会非常不同。在 C 中,我可能会编写代码来管理更大的内存块并使用相邻的指针来存储相关数据。
在 Java 中,我不能(也不想)知道很多关于特定运行时将如何管理内存的信息。所以我也必须将优化提升到更高的抽象层次。我的问题基本上是,我该怎么做?对于引用的局部性,在我在 Java 中工作的抽象级别上,“紧密结合”是什么意思?同一个对象?同类型?同一个数组?
一般来说,我不认为抽象层会改变“物理定律”,打个比方。每次空间不足时将数组大小加倍也是 Java 中的一个好策略,即使您不再调用 malloc()
。
最佳答案
Java 获得良好性能的关键是编写惯用的代码,而不是试图智取 JIT 编译器。如果您编写代码试图影响它以某种方式在 native 指令级别执行操作,那么您更有可能自取其辱。
这并不是说引用位置等共同原则无关紧要。它们确实如此,但我认为使用数组等是性能感知、惯用代码,但并不“棘手”。
HotSpot 和其他优化运行时在如何为特定处理器优化代码方面非常聪明。 (例如,check out this discussion. )如果我是专业的机器语言程序员,我会编写机器语言,而不是 Java。如果我不是,那么认为我可以比专家更好地优化我的代码是不明智的。
此外,即使您确实知道为特定 CPU 实现某些东西的最佳方式,Java 的美妙之处还是一次编写,随处运行。 “优化”Java 代码的巧妙技巧往往会使 JIT 更难识别优化机会。遵循常见习惯用法的直截了当的代码更容易被优化器识别。因此,即使您为您的测试平台获得了最好的 Java 代码,该代码也可能在不同的架构上表现得很糟糕,或者充其量无法利用 future JIT 中的增强功能。
如果您想要良好的性能,请保持简单。 真正聪明人的团队正在努力加快速度。
关于java - 我可以在 Java 代码中做什么来优化 CPU 缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1478280/
我有一个关于 JavaScript 语法的问题。实际上,我在自学 MEAN 堆栈教程时想出了编码(https://thinkster.io/mean-stack-tutorial#adding-aut
在我的书中它使用了这样的东西: for($ARGV[0]) { Expression && do { print "..."; last; }; ... } for 循环不完整吗?另外,do 的意义何
我已经编写了读取开关状态的代码,如果按 3 次 # 则退出。 void allkeypadTest(void) { static uint8_t modeKeyCount=0; do
因此,对于上周我必须做的作业,我必须使用 4 个 do-while 循环和 if 语句在 Java 中制作一个猜谜游戏。我无法成功完成它,类(class)已经继续,没有为我提供任何帮助。如果有人可以查
int i=1,j=0,n=10,k; do{ j+=i; i<<1; printf("%d\n",i); // printf("%d\n",12<<1); }while
此代码用于基本杂货计算器的按钮。当我按下按钮时,一个输入对话框会显示您输入商品价格的位置。我遇到的问题是我无法弄清楚如何获得 do ... while 循环以使输入对话框在输入后弹出。 我希望它始终恢
当我在循环中修改字符串或另一个变量时,它的条件是否每次都重新计算?或者在循环开始前一次 std::string a("aa"); do { a = "aaaa"; } while(a.size<10)
我刚刚写了这个,但我找不到问题。我使用代码块并编写了这个问题 error: expected 'while' before '{' token === Build finished: 1 errors
do { printf("Enter number (0-6): ", ""); scanf("%d", &Num); }while(Num >= 0 && Num 表示“超过”,<表
我有一个包含 10 个项目的 vector (为简单起见,所有项目都属于同一类,称其为“a”)。我想要做的是检查“A”不是 a) 隐藏墙壁或 b) 隐藏另一个“A”。我有一个碰撞函数可以做到这一点。
嗨,这是我的第二个问题。我有下表 |-----|-------|------|------| |._id.|..INFO.|.DONE.|.LAST.| |..1..|...A...|...N..|.
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: Why are there sometimes meaningless do/while and if/e
来自 wikibook在 F# 上有一小部分它说: What does let! do?# let! runs an async object on its own thread, then it i
我在 Real World Haskell 书中遇到了以下函数: namesMatching pat | not (isPattern pat) = do exists do
我有一个类似于下面的用例,我创建了多个图并使用 gridExtra 将它们排列到一些页面布局中,最后使用 ggsave 将其保存为 PDF : p1 % mutate(label2
当我使用具有 for 循环的嵌套 let 语句时,如果没有 (do (html5 ..)),我将无法运行内部 [:tr]。 (defpartial column-settings-layout [&
执行 vagrant up 时出现此错误: anr@anr-Lenovo-G505s ~ $ vagrant up Bringing machine 'default' up with 'virtua
# ################################################# # Subroutine to add data to the table Blas
我想创建一个检查特定日期格式的读取主机。此外,目标是检查用户输入是否正确,如果不正确,则提示应再次弹出。 当我刚接触编程时,发现了这段代码,这似乎很合适。我仍然在努力“直到” do {
我关注这个tutorial在谷歌云机器学习引擎上进行培训。我一步一步地跟着它,但是在将 ml 作业提交到云时我遇到了错误。我运行了这个命令。 sam@sam-VirtualBox:~/models/r
我是一名优秀的程序员,十分优秀!