java模拟具有固定工作量的持续性任务
我正在模拟一个CPU受限的任务。每个CPU受限的任务计算800的阶乘。每个CPU绑定的任务都是线程执行的可运行对象。当我增加线程数(每个线程运行一个可运行的tak)时,我发现一些线程运行得非常快,以至于服务时间趋于零。我无法理解这种行为。代码如下
import java.math.BigInteger;
public class CpuBoundJob implements Runnable {
public void run() {
BigInteger factValue = BigInteger.ONE;
long t1=System.nanoTime();
for ( int i = 2; i <= 800; i++){
factValue = factValue.multiply(BigInteger.valueOf(i));
}
long t2=System.nanoTime();
System.out.println("Service Time(ms)="+((double)(t2-t1)/1000000));
}
}
public class TaskRunner extends Thread {
CpuBoundJob job=new CpuBoundJob();
public void run(){
job.run();
}
}
public class Test {
int numberOfThreads=5;
public Test(){
for(int i=1;i<=numberOfThreads;i++){
TaskRunner t=new TaskRunner();
t.start();
}
}
public static void main(String[] args) {
new Test();
}
}
如果有5个线程,输出如下
Service Time(ns)=28.765821
Service Time(ns)=33.489663
Service Time(ns)=29.19727
Service Time(ns)=34.259404
Service Time(ns)=37.347448
如果有10个线程,输出如下
Service Time(ns)=45.647232
Service Time(ns)=3.972654
Service Time(ns)=23.494475
Service Time(ns)=12.210069
Service Time(ns)=19.382478
Service Time(ns)=15.34706
Service Time(ns)=54.769652
Service Time(ns)=20.646827
Service Time(ns)=3.28936
Service Time(ns)=29.809905
Service Time(ns)=60.798897
Service Time(ns)=50.718839
Service Time(ns)=2.727253
Service Time(ns)=2.882779
Service Time(ns)=63.864835
Service Time(ns)=42.601425
Service Time(ns)=4.029496
Service Time(ns)=4.339761
Service Time(ns)=79.396239
Service Time(ns)=2.923832
Service Time(ns)=5.773848
Service Time(ns)=3.064359
Service Time(ns)=2.446592
Service Time(ns)=2.205802
Service Time(ns)=2.212513
Service Time(ns)=2.265408
Service Time(ns)=82.51073
Service Time(ns)=2.200276
Service Time(ns)=2.289487
Service Time(ns)=2.322645
Service Time(ns)=2.201459
Service Time(ns)=2.217644
Service Time(ns)=2.197908
Service Time(ns)=2.252381
Service Time(ns)=13.564814
Service Time(ns)=2.238171
Service Time(ns)=2.199486
Service Time(ns)=2.179355
Service Time(ns)=2.237381
Service Time(ns)=2.593041
Service Time(ns)=2.444225
Service Time(ns)=2.42054
Service Time(ns)=38.745219
Service Time(ns)=81.232565
Service Time(ns)=19.612216
Service Time(ns)=22.31381
Service Time(ns)=59.521916
Service Time(ns)=59.511258
Service Time(ns)=54.439255
Service Time(ns)=11.582434
我无法理解2.4等的服务时间,有时服务时间降至0.8。为什么运行固定工作量的线程执行得如此之快
# 1 楼答案
你是怎么开始这些测试的?如果每次都冷启动它们,我怀疑JVM是“warming up”和Just In Time compiling代码。如果是这种情况,那么带有几个线程的测试将以解释代码的形式运行,随后的运行将被编译,甚至以后的运行也会根据以前的运行进行优化The JVM is magic that way
降低优化影响的想法:
# 2 楼答案
在某个时刻,JIT可能会启动并优化代码。尝试通过先“预热”系统来运行实验,即进行N次迭代(你需要试验N的最佳值),在不进行测量的情况下运行系统,然后进行测量,例如:
}
还打印从{{CD1>}内的统计数据有问题,考虑将它们积聚在一些集合中,并在测试完成后打印它们。
# 3 楼答案
很可能是计时功能太不准确,无法测量如此快速的操作。试试100000的阶乘或类似的东西
nanotime
方法的文件称,它不能保证提供纳秒精度: