我正在为 N-Body 问题实现 Barnes-Hut 算法的多线程解决方案。
主类执行以下操作
public void runSimulation() {
for(int i = 0; i < numWorkers; i++) {
new Thread(new Worker(i, this, gnumBodies, numSteps)).start();
}
try {
startBarrier.await();
stopBarrier.await();
} catch (Exception e) {e.printStackTrace();}
}
bh.stop- 和 bh.startBarrier 是 CyclicBarriers 将 start- 和 stopTime 设置为 System.nanoTime(); 到达时(障碍动作)。
工人运行方法:
public void run() {
try {
bh.startBarrier.await();
for(int j = 0; j < numSteps; j++) {
for(int i = wid; i < gnumBodies; i += bh.numWorkers) {
bh.addForce(i);
bh.moveBody(i);
}
bh.barrier.await();
}
bh.stopBarrier.await();
} catch (Exception e) {e.printStackTrace();}
}
addForce(i) 遍历一棵树并进行一些计算。它不会影响任何共享变量,因此不使用同步。O(NlogN)。
moveBody(i) 对一个元素进行计算并且不使用同步。上)。
当达到 bh.barrier 时,就会建立一个包含所有实体的树(屏障动作)。
现在来解决问题。运行时间随着使用的线程数线性增加。gnumBodies = 240,numSteps = 85000 和四个核心的运行时:
- 1 个线程 = 0.763
- 2 个线程 = 0.952
- 3 个线程 = 1.261
- 4 个线程 = 1.563
为什么运行时不会随着使用的线程数而减少?
编辑:添加硬件信息