乱数の比較的短い (5 ~ 100 要素) 配列を多数 (現在は数百万、最終的には数十億) 消費し、それらを使用してあまり精力的ではない計算を行うコードがあります。乱数は、まあ、ランダムです。理想的には、複数のコアで乱数を生成したいと思います。これは、乱数の生成がプロファイリングの実行時間の 50% を超えるためです。ただし、シングルスレッドのアプローチよりも遅くない方法で多数の小さなタスクを分散するのは困難です。
私のコードは現在、次のようになっています。
for(int i=0;i<1000000;i++){
for(RealVector d:data){
while(!converged){
double[] shortVec = new double[5];
for(int i=0;i<5;i++) shortVec[i]=rng.nextGaussian();
double[] longerVec = new double[50];
for(int i=0;i<50;i++) longerVec[i]=rng.nextGaussian();
/*Do some relatively fast math*/
}
}
}
うまくいかなかった私が取ったアプローチは次のとおりです。
- 1 つ以上のスレッドが ArrayBlockingQueue にデータを入力し、メイン ループが配列を消費してデータを入力します (ここでは、ボックス化/ボックス化解除がキラーでした)
- 数学の非依存部分を実行しながら、Callable を使用してベクトルを生成する (未来を生成する) (間接処理のオーバーヘッドが、私が得た並列処理の利点を上回っているようです)
- 2 つの ArrayBlockingQueue を使用し、それぞれがスレッドによって読み込まれます。1 つは短い配列用で、もう 1 つは長い配列用です (直接シングル スレッドの場合よりも約 2 倍遅くなります)。
私は、小さな独立したプリミティブの大きなストリームを並行して生成し、それらを単一のスレッドから消費するという一般的なケースを処理する方法ほど、特定の問題に対する「解決策」を探しているわけではありません。