我正在嘗試計算Pi,但是當使用多個線程時,我真正想實現的是效率。該算法很簡單:我在單位正方形中隨機生成點,然後計算它們中有多少個正方形內的圓。 (更多這裏:http://math.fullerton.edu/mathews/n2003/montecarlopimod.html) 我的想法是水平拆分方塊,併爲它的每個部分運行不同的線程。但是不是加快速度,我得到的只是一個延遲。任何想法爲什麼?下面是代碼:如何加快使用多線程的計算?
public class TaskManager {
public static void main(String[] args) {
int threadsCount = 3;
int size = 10000000;
boolean isQuiet = false;
PiCalculator pi = new PiCalculator(size);
Thread tr[] = new Thread[threadsCount];
long time = -System.currentTimeMillis();
int i;
double s = 1.0/threadsCount;
int p = size/threadsCount;
for(i = 0; i < threadsCount; i++) {
PiRunnable r = new PiRunnable(pi, s*i, s*(1.0+i), p, isQuiet);
tr[i] = new Thread(r);
}
for(i = 0; i < threadsCount; i++) {
tr[i].start();
}
for(i = 0; i < threadsCount; i++) {
try {
tr[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
double myPi = 4.0*pi.getPointsInCircle()/pi.getPointsInSquare();
System.out.println(myPi + " time = " + (System.currentTimeMillis()+time));
}
}
public class PiRunnable implements Runnable {
PiCalculator pi;
private double minX;
private double maxX;
private int pointsToSpread;
public PiRunnable(PiCalculator pi, double minX, double maxX, int pointsToSpread, boolean isQuiet) {
super();
this.pi = pi;
this.minX = minX;
this.maxX = maxX;
this.pointsToSpread = pointsToSpread;
}
@Override
public void run() {
int n = countPointsInAreaInCircle(minX, maxX, pointsToSpread);
pi.addToPointsInCircle(n);
}
public int countPointsInAreaInCircle (double minX, double maxX, int pointsCount) {
double x;
double y;
int inCircle = 0;
for (int i = 0; i < pointsCount; i++) {
x = Math.random() * (maxX - minX) + minX;
y = Math.random();
if (x*x + y*y <= 1) {
inCircle++;
}
}
return inCircle;
}
}
public class PiCalculator {
private int pointsInSquare;
private int pointsInCircle;
public PiCalculator(int pointsInSquare) {
super();
this.pointsInSquare = pointsInSquare;
}
public synchronized void addToPointsInCircle (int pointsCount) {
this.pointsInCircle += pointsCount;
}
public synchronized int getPointsInCircle() {
return this.pointsInCircle;
}
public synchronized void setPointsInSquare (int pointsInSquare) {
this.pointsInSquare = pointsInSquare;
}
public synchronized int getPointsInSquare() {
return this.pointsInSquare;
}
}
的一些結果: - 對於3個線程: 「3.1424696時間= 2803」 - 用於1線: 「3.1416192時間= 2337」
您是否在多核系統上運行? – ribram 2011-06-07 19:35:59
我在intel core 2上運行。 – 2011-06-07 19:40:45
他在加入之前就開始了他們,所以這很好。如果你只有2個內核,那麼使用2個以上的線程是沒有用的。由於上下文切換的開銷,您的應用程序純粹受CPU限制,因此比內核多的線程會減慢速度。 – ribram 2011-06-07 19:54:42