首先,再次,感谢已经回答了我的问题.我不是一个非常有经验的程序员,这是我第一次使用多线程.
我得到了一个像我的问题一样工作的例子.我希望这可以缓解我们的情况.
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,它比串行处理更慢.每次我需要解决批次时,似乎需要花费太多时间来创建新的Tread.
有没有更好的方法来处理这个问题?我使用的这些池似乎适用于每个线程花费更多时间而不是数千个更小线程的情况……
谢谢!
最好的祝福!
解决方法:
从我读过的内容:“成千上万的独立计算……同时发生……运行需要几毫秒”在我看来,你的问题非常适合GPU编程.
我认为它回答了你的问题. GPU编程正变得越来越流行.有CUDA和Java的Java绑定. OpenCL的.如果你有可能使用它,我说去吧.