私は、既存のシングル スレッド モンテカルロ シミュレーションを使用して最適化する任務を負っています。これは ac# コンソール アプリです。db アクセスはありません。データは csv ファイルから 1 回読み込まれ、最後に書き出されます。そのため、ほとんど CPU バウンドであり、約 50 MB のメモリしか使用しません。
Jetbrains dotTrace プロファイラーで実行しました。合計実行時間の約 30% が一様乱数の生成であり、24% が一様乱数から正規分布乱数への変換です。
基本的なアルゴリズムは、多数のネストされた for ループであり、中心に乱数呼び出しと行列乗算があり、各反復は double を返し、結果リストに追加されます。このリストは定期的にソートされ、いくつかの収束基準についてテストされます (チェック時)。総反復回数の 5% ごとにポイントします) 許容できる場合、プログラムはループから抜け出し、結果を書き込みます。そうでない場合は、最後に進みます。
開発者に検討してもらいたい:
- 新しい Thread v ThreadPoolを使用する必要がありますか
- Microsoft Parallels Extension ライブラリを確認する必要があります
- AForge.Net Parallel.For、http://code.google.com/p/aforge/他のライブラリを見る必要がありますか?
並列コードやマルチスレッド コードを書いたことがないので、上記のチュートリアルへのリンクは大歓迎です。
- 大量の正規分布乱数を生成し、それらを消費するための最良の戦略。一様乱数は、アプリによってこの状態で使用されることはなく、常に正規分布に変換されてから消費されます。
- 乱数生成のための優れた高速ライブラリ (並列?)
- このパラレルを使用する際のメモリの考慮事項、必要な追加の量。
現在のアプリは 500,000 回の反復に 2 時間かかります。ビジネスではこれを 3,000,000 回の反復にスケーリングし、1 日に複数回呼び出す必要があるため、かなりの最適化が必要です。
特に、Microsoft Parallels ExtensionまたはAForge.Net Parallelを使用したことのある方からのご意見をお待ちしております
これはかなり迅速に製品化する必要があるため、.net 4 ベータ版は公開されていますが、同時実行ライブラリが組み込まれていることはわかっています。.net 4 がリリースされたら、後でトラックに移行することを検討できます。今のところ、サーバーには .Net 2 があり、私の開発ボックスにある .net 3.5 SP1 へのアップグレードを審査のために提出しました。
ありがとう
アップデート
Parallel.For の実装を試してみましたが、奇妙な結果が得られました。シングルスレッド:
IRandomGenerator rnd = new MersenneTwister();
IDistribution dist = new DiscreteNormalDistribution(discreteNormalDistributionSize);
List<double> results = new List<double>();
for (int i = 0; i < CHECKPOINTS; i++)
{
results.AddRange(Oblist.Simulate(rnd, dist, n));
}
に:
Parallel.For(0, CHECKPOINTS, i =>
{
results.AddRange(Oblist.Simulate(rnd, dist, n));
});
Simulate 内で rnd.nextUniform() への呼び出しが多数あります。同じ値を多数取得していると思いますが、これは現在並列になっているため発生する可能性がありますか?
また、List AddRange 呼び出しがスレッド セーフではないという問題もありますか? 私はこれを見る
System.Threading.Collections.BlockingCollection は使用する価値があるかもしれませんが、AddRange のない Add メソッドしかないため、その結果を調べて、スレッド セーフな方法で追加する必要があります。Parallel.For を使用したことのある方からの洞察をお待ちしております。Mersenne Twister の実装で nextUniform を呼び出すときに例外が発生したため、一時的にSystem.Randomに切り替えました。おそらく、特定の配列が範囲外のインデックスを取得していたため、スレッドセーフではありませんでした....