gpt4 book ai didi

java - 优化java循环内的空检查?

转载 作者:行者123 更新时间:2023-12-01 07:43:51 25 4
gpt4 key购买 nike

我正在编写一个算法,其中效率非常重要。有时我也想通过调用一些“回调”函数来跟踪算法行为。假设我的代码如下所示:

public float myAlgorithm(AlgorithmTracker tracker) {
while (something) { // millions of iterations
doStuff();
if (tracker != null) tracker.incrementIterationCount(); // <--- How to run the if only once?
doOtherStaff();
}
}

如何防止 if 语句执行一百万次?编译器是否发现 tracker 从未被重新分配?如果第一次检查时为空,则它将始终为空。如果不是,就永远不会。

理想情况下,我想告诉编译器以这样的方式构建我的代码,以便如果 tracker 为空(在运行时),它将以与

相同的性能运行
    while (something) { // millions of iterations
doStuff();
doOtherStaff();
}

我想到了两种解决方案:

  • 我可以编写两个版本的 myAlgorithm,一种包含调用,另一种不包含调用,但这会导致大量代码重复。

  • 我可以将 AlgorithmTracker 提取到一个接口(interface),并使用空函数创建一个假的空跟踪器。不过,我不知道编译器是否会优化调用。

最佳答案

对于大多数 CPU 架构,您不必担心要应用的优化,因为该特定优化是大多数现代 CPU 的一部分。它被称为分支预测,当前的 CPU 在这方面非常擅长。

平均而言,CPU 执行的每 6 条指令就是一个分支,如果对于每个分支,CPU 都必须等待并评估分支条件,则会导致执行速度变慢。

分支预测和推测执行

因此,当面对分支时,在不评估分支条件的情况下,CPU 开始执行(推测执行)一条它认为很可能正确的路径,并在稍后阶段当结果为分支条件成立,CPU 检查是否正在执行正确的路径。

如果CPU选择的路径与分支条件的结果一致,那么CPU就知道它正在执行正确的路径,因此它会以100%的速度继续前进,否则它将不得不刷新它推测执行的所有指令并从正确的路径开始。

但是CPU如何知道选择哪条路径呢?

进入CPU的分支预测器子系统。在其最基本的形式中,它将存储有关分支过去行为的信息,例如,如果某个分支在一段时间内没有被采摘,那么它现在很可能不会被采摘。这是一个简单的解释,真正的分支预测器将非常复杂。

那么这些分支预测器的效果如何?

鉴于分支预测器的核心只是模式匹配机,如果您的分支显示可预测的模式,那么您可以放心分支预测器会正确执行。但是如果您的分支根本没有显示任何模式,那么分支预测器将不会帮助您,最糟糕的是,它会因为所有错误的预测而阻碍您的代码执行。


您的代码将如何与分支预测器一起工作?

在您的情况下,分支控制变量的值永远不会改变,因此分支要么在循环的每次迭代中被选取,要么永远不会被选取。这清楚地表明了一种即使是最基本的分支预测器也能识别的模式。这意味着您的代码实际上将像条件不存在一样执行,因为在最初几次迭代之后,分支预测器将能够以 100% 的准确度选择路径。

要了解更多信息,请阅读 this太棒了,所以线程

有趣的事实:这种特殊的优化是 CPU 漏洞(例如 Spectre 和 Meltdown)的原因

关于java - 优化java循环内的空检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59393977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com