我的程序试图用一定数量的线程对一个范围进行求和,以便并行运行它,但似乎只有一个线程运行时优于4(我有一个8核CPU)。这是我第一次使用Java进行多线程处理,所以我的代码可能会出现问题需要更长的时间吗?
目前我的基准(0-10000的总和)是:
1个主题:1350微秒(平均) 2线程:1800微秒(平均) 4线程:2400微秒(平均) 8个螺纹:3300微秒(平均值)
提前致谢!
/*
Compile: javac RangeSum.java
Execute: java RangeSum nThreads initRange finRange
*/
import java.util.ArrayList;
import java.util.concurrent.*;
public class RangeSum implements Runnable {
private int init;
private int end;
private int id;
static public int out = 0;
Object lock = new Object();
public synchronized static void increment(int partial) {
out = out + partial;
}
public RangeSum(int init,int end) {
this.init = init;
this.end = end;
}//parameters to pass in threads
// the function called for each thread
public void run() {
int partial = 0;
for(int k = this.init; k < this.end; k++)
{
partial = k + partial + 1;
}
increment(partial);
}//thread: sum its id to the out variable
public static void main(String args[]) throws InterruptedException {
final long startTime = System.nanoTime()/1000;//start time: microsecs
//get command line values for
int NumberOfThreads = Integer.valueOf(args[0]);
int initRange = Integer.valueOf(args[1]);
int finRange = Integer.valueOf(args[2]);
//int[] out = new int[NumberOfThreads];
// an array of threads
ArrayList<Thread> Threads = new ArrayList<Thread>(NumberOfThreads);
// spawn the threads / CREATE
for (int i = 0; i < NumberOfThreads; i++) {
int initial = i*finRange/NumberOfThreads;
int end = (i+1)*finRange/NumberOfThreads;
Threads.add(i, new Thread(new RangeSum(initial,end)));
Threads.get(i).start();
}
// wait for the threads to finish / JOIN
for (int i = 0; i < NumberOfThreads; i++) {
try {
Threads.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("All threads finished!");
System.out.println("Total range sum: " + out);
final long endTime = System.nanoTime()/1000;//end time
System.out.println("Time elapsed: "+(endTime - startTime));
}
}
答案 0 :(得分:1)
您的工作负载完全在内存非阻塞计算中 - 基于一般原则,在这种情况下,单个线程将比多线程更快地完成工作。
多个线程往往会干扰L1 / L2 CPU缓存,并为上下文带来额外的开销 切换
具体来说,对于您的代码,您过早地初始化Threads
并测量线程设置时间以及完成它们所需的实际时间。最好先设置final long startTime =...
for (int i = 0; i < NumberOfThreads; i++) {
Thread.get(i).start()
}
列表,然后再设置:
{{1}}
但实际上,在这种情况下,多线程将改善处理时间的期望是不合理的。