我正在尝试熟悉java多线程应用程序。我试着想一个简单的应用程序,可以很好地并行化。我认为向量加法是一个很好的应用。然而,当在我的linux服务器(有4个内核)上运行时,我没有得到任何加速。在4,2,1线程上执行的时间大致相同。
下面是我想到的代码:
public static void main(String[]args)throws InterruptedException{
final int threads = Integer.parseInt(args[0]);
final int length= Integer.parseInt(args[1]);
final int balk=(length/threads);
Thread[]th = new Thread[threads];
final double[]result =new double[length];
final double[]array1=getRandomArray(length);
final double[]array2=getRandomArray(length);
long startingTime =System.nanoTime();
for(int i=0;i<threads;i++){
final int current=i;
th[i]=new Thread(()->{
for(int k=current*balk;k<(current+1)*balk;k++){
result[k]=array1[k]+array2[k];
}
});
th[i].start();
}
for(int i=0;i<threads;i++){
th[i].join();
}
System.out.println("Time needed: "+(System.nanoTime()-startingTime));
}
长度总是线程的倍数,getrandomarray()创建一个介于0和1之间的随机双精度数组。
单线程执行时间:84579446ns
双线程执行时间:74211325ns
4线程执行时间:89215100ns
长度=10000000
下面是getrandomarray()的代码:
private static double[]getRandomArray(int length){
Random random =new Random();
double[]array= new double[length];
for(int i=0;i<length;i++){
array[i]=random.nextDouble();
}
return array;
}
如果有任何帮助,我将不胜感激。
2条答案
按热度按时间ig9co6j11#
对于以下代码,差异是可以观察到的。试试看。
首先你需要预热你的代码。这样,您将度量编译后的代码。前两个迭代具有相同(大约)的时间,但下一个将不同。我还把double改成了boolean,因为我的机器没有太多内存。这使我能够分配一个巨大的数组,同时也使工作占用更多的cpu。
评论中有一个链接。我建议你读一下。
u59ebvdq2#
嗨,从我的Angular 来看,如果你想看看你的核心共享是如何工作的,你可以为所有的核心做一个非常简单的任务,但是要让它们在不同线程之间不断地处理一些不共享的东西(基本上是模拟例如merge sort,线程正在处理一些复杂的事情,并且在很短的时间内使用共享资源)。我用你的代码做了这样的事。在这种情况下,你应该看到几乎完全2倍的速度和4倍的速度。
你看,在你的代码中,大部分时间都是通过构建大表来消耗的,然后线程执行得非常快,它们的工作速度非常快,以至于你对时间的计算是错误的,因为大部分时间都是通过创建线程来消耗的。当我调用在预先计算的循环上工作的代码时,如下所示:
它的运行速度比使用两个线程的代码快两倍。我希望你能理解我在这件事上的意思,当我给我的线程更多的无意义的工作时,你会明白我的观点。