Java多线程向量加法
我试图熟悉java多线程应用程序。我试图想出一个简单的应用程序,可以很好地并行化。我认为向量加法是一个很好的应用。 然而,当在我的linux服务器(有4个内核)上运行时,我没有得到任何加速。在4,2,1线程上执行的时间大致相同 下面是我想到的代码:Java多线程向量加法,java,multithreading,parallel-processing,thread-safety,Java,Multithreading,Parallel Processing,Thread Safety,我试图熟悉java多线程应用程序。我试图想出一个简单的应用程序,可以很好地并行化。我认为向量加法是一个很好的应用。 然而,当在我的linux服务器(有4个内核)上运行时,我没有得到任何加速。在4,2,1线程上执行的时间大致相同 下面是我想到的代码: public static void main(String[]args)throws InterruptedException{ final int threads = Integer.parseInt(args[0]);
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));
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
final int threads=Integer.parseInt(args[0]);
final int length=Integer.parseInt(args[1]);
最终内螺纹=长度/螺纹;
线程[]th=新线程[线程];
最终双精度[]结果=新双精度[长度];
最终双[]数组1=getRandomArray(长度);
最终双[]数组2=getRandomArray(长度);
长启动时间=System.nanoTime();
对于(int i=0;i{
对于(int k=current*balk;k来说,以下代码的差异是可以观察到的。试试看
public static void main(String[]args)throws InterruptedException{
for(int z = 0; z < 10; z++) {
final int threads = 1;
final int length= 100_000_000;
final int balk=(length/threads);
Thread[]th = new Thread[threads];
final boolean[]result =new boolean[length];
final boolean[]array1=getRandomArray(length);
final boolean[]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)*1.0/1000/1000);
boolean x = false;
for(boolean d : result) {
x |= d;
}
System.out.println(x);
}
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
对于(intz=0;z<10;z++){
最终内螺纹=1;
最终整数长度=100_000_000;
最终内螺纹=长度/螺纹;
线程[]th=新线程[线程];
最终布尔值[]结果=新布尔值[长度];
最终布尔值[]数组1=getRandomArray(长度);
最终布尔值[]数组2=getRandomArray(长度);
长启动时间=System.nanoTime();
对于(int i=0;i{
对于(int k=current*balk;k来说,以下代码的差异是可以观察到的。试试看
public static void main(String[]args)throws InterruptedException{
for(int z = 0; z < 10; z++) {
final int threads = 1;
final int length= 100_000_000;
final int balk=(length/threads);
Thread[]th = new Thread[threads];
final boolean[]result =new boolean[length];
final boolean[]array1=getRandomArray(length);
final boolean[]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)*1.0/1000/1000);
boolean x = false;
for(boolean d : result) {
x |= d;
}
System.out.println(x);
}
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
对于(intz=0;z<10;z++){
最终内螺纹=1;
最终整数长度=100_000_000;
最终内螺纹=长度/螺纹;
线程[]th=新线程[线程];
最终布尔值[]结果=新布尔值[长度];
最终布尔值[]数组1=getRandomArray(长度);
最终布尔值[]数组2=getRandomArray(长度);
长启动时间=System.nanoTime();
对于(int i=0;i{
对于(int k=current*balk;kHi,从我的角度来看,如果您试图了解您的内核是如何共享工作的,那么您可以为所有内核创建非常简单的任务,但要让它们在不同线程之间不共享的内容上持续工作(基本上是为了模拟例如合并排序,其中线程正在处理一些复杂的事情,并在很短的时间内使用共享资源)。使用您的代码,我做了类似的事情。在这种情况下,您应该会看到几乎2倍的加速和4倍的加速
public static void main(String[]args)throws InterruptedException{
for(int a=0; a<5; a++) {
final int threads = 2;
final int length = 10;
final int balk = (length / threads);
Thread[] th = new Thread[threads];
System.out.println(Runtime.getRuntime().availableProcessors());
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(() -> {
Random random = new Random();
int meaningless = 0;
for (int k = current * balk; k < (current + 1) * balk; k++) {
result[k] = array1[k] + array2[k];
for (int j = 0; j < 10000000; j++) {
meaningless+=random.nextInt(10);
}
}
});
th[i].start();
}
for (int i = 0; i < threads; i++) {
th[i].join();
}
System.out.println("Time needed: " + ((System.nanoTime() - startingTime) * 1.0) / 1000000000 + " s");
}
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
对于(int a=0;a{
随机=新随机();
int=0;
对于(int k=当前*balk;k<(当前+1)*balk;k++){
结果[k]=array1[k]+array2[k];
对于(int j=0;j<10000000;j++){
无意义+=随机。nextInt(10);
}
}
});
th[i].start();
}
对于(int i=0;i
你看,在你的代码中,大部分时间都被用来构建大表,然后线程执行得非常快,它们的工作速度如此之快,以至于你对时间的计算是错误的,因为大部分时间都被用来创建线程。当我调用在预计算循环上工作的代码时,如下所示:
long startingTime =System.nanoTime();
for(int k=0; k<length; k++){
result[k]=array1[k]|array2[k];
}
System.out.println("Time needed: "+(System.nanoTime()-startingTime));
long startingTime=System.nanoTime();
对于(int k=0;kHi,从我的角度来看),如果您试图了解您的核心是如何共享工作的,那么您可以为所有核心创建非常简单的任务,但要让它们在不同线程之间不共享的内容上持续工作(基本上是为了模拟例如合并排序,其中线程正在处理一些复杂的事情,并在很短的时间内使用共享资源)。使用您的代码,我做了类似的事情。在这种情况下,您应该会看到几乎2倍的加速和4倍的加速
public static void main(String[]args)throws InterruptedException{
for(int a=0; a<5; a++) {
final int threads = 2;
final int length = 10;
final int balk = (length / threads);
Thread[] th = new Thread[threads];
System.out.println(Runtime.getRuntime().availableProcessors());
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(() -> {
Random random = new Random();
int meaningless = 0;
for (int k = current * balk; k < (current + 1) * balk; k++) {
result[k] = array1[k] + array2[k];
for (int j = 0; j < 10000000; j++) {
meaningless+=random.nextInt(10);
}
}
});
th[i].start();
}
for (int i = 0; i < threads; i++) {
th[i].join();
}
System.out.println("Time needed: " + ((System.nanoTime() - startingTime) * 1.0) / 1000000000 + " s");
}
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
对于(int a=0;a{
随机=新随机();
int=0;
对于(int k=当前*balk;k<(当前+1)*balk;k++){
结果[k]=array1[k]+array2[k];
对于(int j=0;j<10000000;j++){
无意义+=随机。nextInt(10);
}
}
});
th[i].start();
}
对于(int i=0;i
你看,在你的代码中,大部分时间都被用来构建大表,然后线程执行得非常快,它们的工作速度如此之快,以至于你对时间的计算是错误的,因为大部分时间都被用来创建线程。当我调用在预计算循环上工作的代码时,如下所示:
long startingTime =System.nanoTime();
for(int k=0; k<length; k++){
result[k]=array1[k]|array2[k];
}
System.out.println("Time needed: "+(System.nanoTime()-startingTime));
long startingTime=System.nanoTime();
对于(int k=0;kDid您尝试过使用大长度值,比如10000000
?我运行了一个长度=10000000的测试,看不到任何加速。请查看代码下面的编辑。您可以将getRandomArray
@KiranKumar的代码发布给我吗?我编辑了我的帖子。这不是做基准测试的方法。您是否尝试过使用大长度值,比如10000000
?我运行了一个长度为10000000的测试,看不到任何加速。请看我在代码下面的编辑。你能给我发getRandomArray
@KiranKumar的代码吗?我编辑了我的文章。这不是做基准测试的方法。非常感谢。我运行了测试,最终可以看到加速:P I