特定の数のスレッドで特定の数のコインをフリップするクラスの単純なコインフリッピング実験を行っています。スピードアップのために私たちのパフォーマンステストを実行するために、固定数のコインフリップ(私は10億を使用しています)を使用してスレッド数を変更します。これらのテストを実行するには、8コアのAWS余分な高CPUインスタンスを使用します。何らかの理由で、6つ以上のスレッドを使用するとすぐに、私は大幅に減速します。それよりも悪い、それは矛盾している。時々私は14秒、時には同じ数のスレッドとフリップで2になるでしょう。意味がない。私は別のJVM(OpenJREとSun JVM)を使い、新しいインスタンスを試してみました。以下は私のコードとベンチマーク結果(ミリ秒)です。私はいくつかの助けが大好きです。ありがとう。6つ以上のスレッドを使用するとパフォーマンスが大幅に低下する
EDIT:それで、私はそれを解決したようです.YadabとBruno Reisの提案に大いに感謝します。彼らは、ローカル変数を使用して頭の数を追跡することを提案しました。これは要因だったと思います。彼らはまた、同じJVMセッション内からすべてのテストを実行することを提案しました。これはほぼ間違いなく要因でした。みんなあなたの助けてくれてありがとう。
Speedup:
Threads | Flips | Time
1 1000000000 16402 16399 16404
2 1000000000 8218 8216 8217
3 1000000000 5493 5483 5492
4 1000000000 4125 4127 4140
5 1000000000 3306 3304 3311
6 1000000000 2758 2766 2756
7 1000000000 8346 7874 10617
8 1000000000 14370 14414 17831
9 1000000000 14956 14764 15316
10 1000000000 13595 14491 14031
11 1000000000 12642 11188 10625
12 1000000000 10620 10629 10876
13 1000000000 8422 9950 9756
14 1000000000 9284 9546 10194
15 1000000000 8524 4134 8046
16 1000000000 6915 6361 7275
コード:
import java.util.Random;
public class CoinFlip implements Runnable {
private final long iterations; //iterations is the number of times the program will run, numHeads is the number of heads counted
private long numHeads;
public CoinFlip(long iterations) {
this.iterations = iterations;
}
@Override
public void run() {
Random rand = new Random();
numHeads = 0;
for (long i = 0; i < iterations; i++) {
if (rand.nextBoolean()) { //True represents heads, false represents a tails
numHeads++;
}
}
}
public long getHeads() { //numHeads getter
return numHeads;
}
public static void main(String[] args) {
final long numIterations , itersPerThread; //iterations: number of iterations, threads: number of threads to run on, itersPerThread: how many iterations each thread is responsible for
final int threads;
if (args.length != 2) {
System.out.println("Usage: java CoinFlip #threads #iterations");
return;
}
try {
threads = Integer.parseInt(args[0]);
numIterations = Long.parseLong(args[1]);
} catch (NumberFormatException e) {
System.out.println("Usage: java CoinFlip #threads #iterations");
System.out.println("Invalid arguments");
return;
}
itersPerThread = numIterations/((long)threads); //Might cause rounding errors, but we were told to ignore that
Thread[] threadList = new Thread[threads]; //List of running threads so we can join() them later
CoinFlip[] flipList = new CoinFlip[threads]; //List of our runnables so that we can collect the number of heads later
for (int i = 0; i < threads; i++) { //create each runnable
flipList[i] = new CoinFlip(itersPerThread);
}
long time = System.currentTimeMillis(); //start time
for (int i = 0; i < threads; i++) { //create and start each thread
threadList[i] = new Thread(flipList[i]);
threadList[i].start();
}
for (int i = 0; i < threads; i++) { //wait for all threads to finish
try {
threadList[i].join();
System.out.println("Collected thread " + i);
} catch (InterruptedException e) {
System.out.println("Interrupted");
return;
}
}
time = System.currentTimeMillis() - time; //total running time
long totHeads = 0;
for (CoinFlip t : flipList) { //Collect number of heads from each CoinFlip object
totHeads += t.getHeads();
}
//Print results
System.out.println(totHeads + " heads in " + (numIterations/threads)
* threads + " coin tosses on " + threads + " threads");
System.out.println("Elapsed time: " + time + "ms");
}
}
テストシステムにはいくつのコアがありますか? – Tudor
アプリケーションにどのくらいのメモリを設定しましたか(-Xmx)? –
テストシステムに8つのコアがあります(そのように編集されています)。私は、メモリの量を設定していない、私はちょうど、デフォルトであったものを使用した。これはおそらく十分なはずです。なぜなら、メモリで何もしていないので、rand.nextBooleanという形での計算です。 –