为什么分支预测比没有分支更快?

8

受到这个问题的启发:为什么处理已排序的数组比未排序的数组更快?

我自己写了一个分支预测实验:

public class BranchPrediction {
    public static void main(final String[] args) {
        long start;
        long sum = 0;

        /* No branch */
        start = System.nanoTime();
        sum = 0;
        for (long i = 0; i < 10000000000L; ++i)
            sum += i;
        System.out.println(System.nanoTime() - start);
        System.out.println(sum);

        /* With branch */
        start = System.nanoTime();
        sum = 0;
        for (long i = 0; i < 10000000000L; ++i)
            if (i >= 0)
                sum += i;
        System.out.println(System.nanoTime() - start);
        System.out.println(sum);

        /* No branch (again) */
        start = System.nanoTime();
        sum = 0;
        for (long i = 0; i < 10000000000L; ++i)
            sum += i;
        System.out.println(System.nanoTime() - start);
        System.out.println(sum);

        /* With branch (again) */
        start = System.nanoTime();
        sum = 0;
        for (long i = 0; i < 10000000000L; ++i)
            if (i >= 0)
                sum += i;
        System.out.println(System.nanoTime() - start);
        System.out.println(sum);
    }
}

结果让我感到困惑:根据程序输出,带有分支的循环比无分支循环更加可靠地快速执行。
示例输出:
7949691477
-5340232226128654848
6947699555
-5340232226128654848
7920972795
-5340232226128654848
7055459799
-5340232226128654848

为什么会这样呢?

编辑:


3
你确定你没有看到编译器/JIT优化的影响吗? - Oliver Charlesworth
3
你必须了解,Java和C++的工作方式不同。首先,阅读@MarkPeters发布的链接,然后重新进行基准测试。 - Luiggi Mendoza
6
尝试在每个测试之间打印sum变量。目前情况下,JIT 可以合法地将所有内容优化掉。 - Mysticial
2
也许HotSpot生成的代码会提供一些启示。 - Marcelo Cantos
显示剩余15条评论
2个回答

4

1
你在其他机器上取得了什么成就? - Dejan
我的其他机器运行Intel Xeon和Intel Core 2,都运行Linux 64位和Oracle JVM。Xeon CPU在循环中没有显示出真正的差异,而Core 2 CPU表明分支循环比无分支循环运行得慢。 - user972946
这个i7处理器在将正数加到负数时一定非常出色。 - user972946
1
我不知道,我有Intel i3,我制作了像上面那样的程序,但是我没有通过if语句和排除来进行优化。 - Dejan

2
请注意,JVM会在内部进行优化执行,并且您的计算机内部有缓存可以使计算更快。由于您拥有如此强大的处理器(许多独立核心),这并不奇怪。还要注意,在Java代码下方运行的代码将映射到计算机的机器代码。只需尽可能优化代码,让JVM自行解决即可。
编辑:机器和硬件喜欢大负载,它们以更高效的方式运行。特别是缓存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接