首先,再次感谢所有已经回答我问题的人。我不是一个经验丰富的程序员,这是我第一次体验多线程。
我有一个与我的问题非常相似的例子。我希望这可以缓解我们的情况。
public class ThreadMeasuring {
private static final int TASK_TIME = 1; //microseconds
private static class Batch implements Runnable {
CountDownLatch countDown;
public Batch(CountDownLatch countDown) {
this.countDown = countDown;
}
@Override
public void run() {
long t0 =System.nanoTime();
long t = 0;
while(t<TASK_TIME*1e6){ t = System.nanoTime() - t0; }
if(countDown!=null) countDown.countDown();
}
}
public static void main(String[] args) {
ThreadFactory threadFactory = new ThreadFactory() {
int counter = 1;
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Executor thread " + (counter++));
return t;
}
};
// the total duty to be divided in tasks is fixed (problem dependent).
// Increase ntasks will mean decrease the task time proportionally.
// 4 Is an arbitrary example.
// This tasks will be executed thousands of times, inside a loop alternating
// with serial processing that needs their result and prepare the next ones.
int ntasks = 4;
int nthreads = 2;
int ncores = Runtime.getRuntime().availableProcessors();
if (nthreads<ncores) ncores = nthreads;
Batch serial = new Batch(null);
long serialTime = System.nanoTime();
serial.run();
serialTime = System.nanoTime() - serialTime;
ExecutorService executor = Executors.newFixedThreadPool( nthreads, threadFactory );
CountDownLatch countDown = new CountDownLatch(ntasks);
ArrayList<Batch> batches = new ArrayList<Batch>();
for (int i = 0; i < ntasks; i++) {
batches.add(new Batch(countDown));
}
long start = System.nanoTime();
for (Batch r : batches){
executor.execute(r);
}
// wait for all threads to finish their task
try {
countDown.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long tmeasured = (System.nanoTime() - start);
System.out.println("Task time= " + TASK_TIME + " ms");
System.out.println("Number of tasks= " + ntasks);
System.out.println("Number of threads= " + nthreads);
System.out.println("Number of cores= " + ncores);
System.out.println("Measured time= " + tmeasured);
System.out.println("Theoretical serial time= " + TASK_TIME*1000000*ntasks);
System.out.println("Theoretical parallel time= " + (TASK_TIME*1000000*ntasks)/ncores);
System.out.println("Speedup= " + (serialTime*ntasks)/(double)tmeasured);
executor.shutdown();
}
}
每个批次不进行计算,而是等待某个给定时间。该程序计算speedup,理论上总是 2,但可能会小于 1(实际上是减速)如果“TASK_TIME”很小。
我的计算最多需要 1 毫秒,而且通常更快。对于 1 毫秒,我发现加速大约为 30%,但在实践中,通过我的程序,我注意到减速.
这段代码的结构与我的程序非常相似,所以如果你能帮助我优化线程处理,我将非常感激。
亲切的问候。
下面是原来的问题:
Hi.
我想在我的程序上使用多线程,因为我相信它可以大大提高效率。它的运行时间大部分是由于独立计算造成的。
我的程序有数千个独立的计算(需要解决几个线性系统),但它们只是由几十个左右的小团体同时发生。每个组都需要几毫秒才能运行。在完成一组计算之后,程序必须按顺序运行一段时间,然后我必须再次求解线性系统。
实际上,可以将其视为要求解的这些独立线性系统位于迭代数千次的循环内,与取决于先前结果的顺序计算交替进行。我加速程序的想法是在并行线程中计算这些独立计算,通过将每个组划分为(我可用的处理器数量)独立计算批次。所以原则上根本不用排队。
我尝试使用FixedThreadPool和CachedThreadPool,它甚至比串行处理还要慢。每次我需要解决批次问题时,似乎都需要花费太多时间来创建新的踏板。
有没有更好的方法来处理这个问题?我使用的这些池似乎适合每个线程花费更多时间而不是数千个较小线程的情况......
谢谢!
此致!