urs*_*dio 3 java multithreading warm-up
我正在处理Java中的多线程,正如有人向我指出的那样,我注意到线程正在热身,它们会在反复执行时变得更快.我想了解为什么会发生这种情况,以及它是否与Java本身有关,或者它是否是每个多线程程序的常见行为.
代码(由Peter Lawrey撰写)举例说明如下:
for (int i = 0; i < 20; i++) {
ExecutorService es = Executors.newFixedThreadPool(1);
final double[] d = new double[4 * 1024];
Arrays.fill(d, 1);
final double[] d2 = new double[4 * 1024];
es.submit(new Runnable() {
@Override
public void run() {
// nothing.
}
}).get();
long start = System.nanoTime();
es.submit(new Runnable() {
@Override
public void run() {
synchronized (d) {
System.arraycopy(d, 0, d2, 0, d.length);
}
}
});
es.shutdown();
es.awaitTermination(10, TimeUnit.SECONDS);
// get a the values in d2.
for (double x : d2) ;
long time = System.nanoTime() - start;
System.out.printf("Time to pass %,d doubles to another thread and back was %,d ns.%n", d.length, time);
}
Run Code Online (Sandbox Code Playgroud)
结果:
Time to pass 4,096 doubles to another thread and back was 1,098,045 ns.
Time to pass 4,096 doubles to another thread and back was 171,949 ns.
... deleted ...
Time to pass 4,096 doubles to another thread and back was 50,566 ns.
Time to pass 4,096 doubles to another thread and back was 49,937 ns.
Run Code Online (Sandbox Code Playgroud)
即它变得更快并稳定在50 ns左右.这是为什么?
如果我运行此代码(20次重复),然后执行其他操作(让我们说先前结果的后处理和另一个多线程轮次的准备),然后再对其执行Runnable相同的操作ThreadPool,再进行20次重复,它将被预热,任何情况?
在我的程序中,我只执行Runnable一个线程(实际上每个处理核心一个,它是一个CPU密集型程序),然后执行一些其他串行处理多次.随着程序的推进,它似乎没有变得更快.也许我能找到一种方法来温暖它......
线程不像JVM那样变暖.
JVM具有所谓的JIT(即时)编译.在程序运行时,它会分析程序中发生的事情并在运行中对其进行优化.它通过获取JVM运行的字节代码并将其转换为运行速度更快的本机代码来实现此目的.它可以通过最适合您当前情况的方式执行此操作,因为它通过分析实际运行时行为来实现.这可以(并非总是)导致极大的优化.甚至比在没有这些知识的情况下编译为本机代码的某些程序更重要.
您可以在http://en.wikipedia.org/wiki/Just-in-time_compilation上阅读更多内容
当代码加载到CPU缓存中时,您可以对任何程序产生类似的影响,但我相信这将是一个较小的差异.
| 归档时间: |
|
| 查看次数: |
953 次 |
| 最近记录: |