简体   繁体   English

为什么JVM不执行代码?

[英]Why JVM does't execute the code?

I'm testing branch prediction, the code like this: 我正在测试分支预测,如下代码:

//first loop
int sortedSum = 0;
long sortedStartTime = System.nanoTime();
for (int i = 0; i < sortedArray.length; i++) {
    if (sortedArray[i] < 0) {
        sortedSum += sortedArray[i];
    }
}
long sortedTime = System.nanoTime() - sortedStartTime;

//second loop
int randomSum = 0;
long randomStartTime = System.nanoTime();
for (int i = 0; i < randomArray.length; i++) {
    if (randomArray[i] < 0) {
        randomSum += randomArray[i];
    }
}
long randomTime = System.nanoTime() - randomStartTime;

System.out.println("random time: " + randomTime);
System.out.println("sorted time: " + sortedTime);

It's simple print the time about each for loop. 简单打印每个for循环的时间。

Note that the sortedSum and randomSum is assigned in the loop but never accessed. 请注意, sortedSumrandomSum在循环中分配,但从未访问过。

We don't talk about the branch prediction here, but the output result. 这里我们不讨论分支预测,而是输出结果。 The output is: 输出为:

random time: 32
sorted time: 1595942

Then, I put the second for loop before the first(first randomArray loop, second sortedArray). 然后,将第二个for循环放在第一个循环之前(第一个randomArray循环,第二个sortedArray)。 The output is: 输出为:

random time: 1541919
sorted time: 40

It seems the JVM doesn't execute the second loop. 看来JVM没有执行第二个循环。 I decompile the class file, the decompiler doesn't erase anything. 我反编译类文件,反编译器不会删除任何内容。

Why? 为什么? And why JVM DO execute the first loop? 以及为什么JVM会执行第一个循环?

PS environment is: PS环境是:

Ubuntu 12.04 LTS
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

When you runtime code enough it triggers the whole method to be optimised (in the background) 当您的运行时代码足够多时,它将触发整个方法的优化(在后台)

This means if you have a loop which iterates over 10K times and it doesn't do anything, you are actually timing how long it takes to detect the loop doesn't do any thing and replace it. 这意味着,如果您有一个循环进行10K次以上且不执行任何操作,则实际上是在计时检测该循环不执行任何操作并替换它所花费的时间。

In the case of the second loop, the method has already been optimise away, in either case. 在第二个循环的情况下,无论哪种情况,该方法都已被优化。

I suggest you have an outer loop which runs this test 3 times and you should see what I mean. 我建议您有一个运行此测试3次的外部循环,您应该明白我的意思。

The reason it can drop the loop is; 它可以放弃循环的原因是:

  • and you don't use the value calculated, so the calculateSum can be dropped 并且您不使用计算出的值,因此可以删除calculateSum
  • then the array access isn't needed 那么就不需要数组访问
  • then the loop itself isn't need. 那么就不需要循环本身。

I suppose this: 这:

We are talking about Just-In-Time Compilation here. 我们在这里谈论即时编译。 The compiler optimizes only some time after he started executing. 编译器在开始执行后仅优化了一段时间。 I would guess that he optimizes everything away. 我猜想他会优化一切。 The first loop is executed as long as the JIT compiler didn't kick in yet. 只要JIT编译器尚未启动,就执行第一个循环。

I think it has nothing to do with Java, but CPU, memory and caches: 我认为这与Java没有关系,但是与CPU,内存和缓存有关:

At first System.nanoTime() app is in memory, the executing code in CPU cache level 1 (at the speed of CPU). 首先, System.nanoTime()应用位于内存中,执行代码处于CPU缓存级别1(以CPU的速度)。 When program starts to execute, CPU will start putting memory blocks ahead in level 1 or 2 cashes, so sequential read/write will see increase in speed. 当程序开始执行时,CPU将开始以1或2级现金的形式将内存块放在前面,因此顺序读/写的速度将会提高。

Try using arrays of size much larger then CPU level 3 cache, eg 10MB and randomized indexes, that is prepare array of indexes in random order. 尝试使用大小比CPU 3级缓存大得多的数组,例如10MB和随机索引,即按随机顺序准备索引数组。 That will eliminate CPU cashing effects. 这将消除CPU兑现的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM