2016-08-23 19 views
1

私はモンテカルロモデルを採用し、マルチスレッド化を使用して高速化を図っています。モンテカルロなので、各シミュレーションは次のシミュレーションとは独立しています。私は手動で数千のシミュレーションを実行し、各シミュレーション結果をデータベースに格納するので、各スレッドを手動で作成したいと思っています。プロセッサにコアがある場合と同じ数のスレッドを作成し、ここで C#でのマルチスレッド化(.Net 4.5)monte-carlo

は(私がシミュレーション数の少ないテストしてい)これを管理するために使用されるコアコードです:

 var threads = new List<Thread>(); 
     iNumCores = Environment.ProcessorCount; 
     iSims = 64; 

     iNumSimsPerThread = iSims/iNumCores; 
     for (int iThread = 0; iThread < iNumCores; iThread++) 
     { 
      iStart = (iThread * iNumSimsPerThread) + 1; 
      iEnd = ((iThread + 1) * iNumSimsPerThread); 

      Thread thread = new Thread(() => ProcessParallelMonteCarloTasks(iStart, iEnd, iSims)); 
      thread.Priority = ThreadPriority.AboveNormal; 
      thread.Start(); 
      threads.Add(thread); 
     } 
     foreach (var thread in threads) 
      thread.Join(); 

私のマシンには8つのコアを持っているので、このテストでは、それぞれが8回のシミュレーションを実行し、8つのスレッドを作成する必要があります。結果のデータをデータベースに書き込むときに、シミュレーション番号が含まれます。私は1つのシミュレーションにつき1行で64行が見込まれます。

しかし、私は40までシミュレーションごとに1行を取得し、

SQL Server results

残念ながら57と64の間の各シミュレーションのための57、次いで3行までのギャップが、私は、デバッグすることができません何が起こっているのか、何故シミュレーションが欠けていて、他のものを複数コピーしているのか分かりません。私はタスクマネージャを開いているとき、プログラムの実行中に3〜4のコアが未使用のままであることがわかります。

どのような考えですか?

更新: Andreのフィードバックに続いて、私はスレッドのスケジューリングと 'ProcessParallelMonteCarloTasks'関数の実行を調べました。

私が気づいた最初のことは、いくつかのスレッドがデータベースへの接続にタイムアウトしていたことです。この例では

Execution order

:私は、コアの数に等しくなるように分プールサイズを変更し、それがその問題を修正しましたが、ここでスレッドが作成される順序であると「ProcessParallelMonteCarloTasksは」を実行しますシミュレーション範囲「17 -24」、「41 -48」、「57 -64」は2回呼び出され、「1-8」、「25 -32」、「49 -56」が欠落しています。

UPDATE 2: タスクマネージャが実行されているため、スレッドの優先度が最も高く設定されています。私が見るところでは、3つのスレッドが1つのコア、2つのスレッドが2つのコア、そして1つのスレッドが第4のコアで実行されていることを示しています。他の4つのコアはかなりアイドルです。コアごとに1つのスレッドを実行する方法はありますか? 1つのコアに3つのスレッドを実行するオーバーヘッドは大きくなければなりません。

+1

あなたの質問はもう少し具体的になりますか?私はこれがマルチスレッドの問題か簡単なSQL INSERTの問題かどうかはわかりません。 1つのタスクが完了するとすぐにデータベースに保存しますか、またはすべてのシミュレーションが完了するのを待ってから、データベースに保存しますか?後者が真実ならば、それぞれの結果をどのように保存しますか?リストに? Dicionary ...? –

+0

これはINSERTには問題ありません。プレスレッディング版はうまくいきます。各シミュレーションが完了すると、データをデータベースに書き込みます(監査証跡の目的で、資産ごとの各シミュレーションの結果を取得する必要があります)。結果はいくつかの個々の数字といくつかの配列から成り立っています。配列は文字列に変換されます。 – John

+0

投稿したコードに間違いはありません。問題はおそらく他の場所(おそらくProcessParallelMonteCarloTasks内)です。 –

答えて

3

iStartおよびiEndはループ内に宣言しなければならず、そうでなければ(自由である)、変更された値を使用中に取得することになります。

+2

Leppie - それは完璧です。それは私のprobemを修正しました!これであなたの助けに感謝します。 – John

+0

@ジョン私は、たとえSQLに後でSQLを渡しても、少なくともSQL以外のどこかのステージング結果を検討したいと思います。 –

+0

ジョナサン - 私はそれを検討しています。シミュレーションが終了した時点で集計結果を表示する必要がありますが、細かいデータをすぐに取得する必要はありません。データベースに書き込む前にデータをステージングする最も効率的な方法について考えてみましょう。 – John

関連する問題