首先,再次感谢所有已经回答我的问题的人。我不是一个非常有经验的程序员,这是我第一次使用多线程。
我得到了一个例子,它的工作方式与我的问题相当类似。我希望它能够减轻我们在这里的情况。
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();
}
}
而不是进行计算,每个批次只需等待一定的时间。程序计算了“加速比”,理论上始终为2,但如果“TASK_TIME”很小,则可能小于1(实际上是“减速”)。
我的计算需要最多1毫秒,通常更快。对于1毫秒,我发现速度略有提高约30%,但在实践中,使用我的程序,我注意到出现了“减速”。
这段代码的结构与我的程序非常相似,因此如果您能帮助我优化线程处理,我将非常感激。
此致敬礼。
以下是原始问题:
嗨。
我想在我的程序上使用多线程,因为我相信这可以大大提高效率。它的大部分运行时间归因于独立计算。
我的程序有数千个独立计算(解决几个线性系统),但它们仅以少量组的形式同时发生,每个组需要几毫秒才能运行。在这些计算组之一之后,程序必须按顺序运行一段时间,然后我必须再次解决线性系统。
实际上,可以看作要解决的这些独立线性系统位于迭代数千次的循环内,与依赖于先前结果的顺序计算交替进行。我加速程序的想法是通过将每个组分成(可用处理器数)个独立计算的批次来在并行线程中计算这些独立计算。因此,原则上根本没有排队。
我尝试使用FixedThreadPool和CachedThreadPool,但它比串行处理还要慢。每次需要解决批次时,似乎花费了太多时间创建新线程。
是否有更好的方法来处理这个问题?我使用的这些池似乎适用于每个线程需要更长时间而不是数千个较小的线程的情况...
谢谢!最好的问候!