文字列内の文字を数える非常に単純なプログラムがあります。整数threadnum
はスレッドの数を設定し、それに応じてデータthreadnum
を各スレッドが処理するチャンクに分割します。
各スレッドは、共有ディクショナリに含まれる値をインクリメントし、文字ヒストグラムを作成します。
private Dictionary<UInt32, int> dict = new Dictionary<UInt32, int>();
- すべてのスレッドが終了するのを待ってメイン プロセスを続行するために、
Thread.Join
- 最初は、後でマージされる各スレッドのローカル ディクショナリがありましたが、共有ディクショナリはロックせずに正常に機能しました。
- メソッドBuildDictionaryでは参照はロックされませんが、ディクショナリのロックはスレッド実行時間に大きな影響を与えませんでした。
- 各スレッドの時間が計測され、結果の辞書が比較されます。
- ディクショナリの内容は、スレッドが 1 つであろうと複数であろうと、同じであるべきです。
- 各スレッドが完了するには、threadnum によって決定される部分が必要です。
問題:
合計時間はおおよそ の倍数ですthreadnum
。つまり、実行時間は増加します。
(残念ながら、現時点では C# プロファイラーを実行できません。さらに、C# 3 コードとの互換性を希望します。)
他の人も同様に苦労している可能性があります。VS 2010 Express Edition の vshostプロセスがスタックし、スレッドが順番に実行されるようにスケジュールしている可能性がありますか?
別の MT パフォーマンスの問題が最近投稿され、「Visual Studio C# 2010 Express Debug running Faster than Release」として投稿されました。
コード:
public int threadnum = 8;
Thread[] threads = new Thread[threadnum];
Stopwatch stpwtch = new Stopwatch();
stpwtch.Start();
for (var threadidx = 0; threadidx < threadnum; threadidx++)
{
threads[threadidx] = new Thread(BuildDictionary);
threads[threadidx].Start(threadidx);
threads[threadidx].Join(); //Blocks the calling thread, till thread completion
}
WriteLine("Total - time: {0} msec", stpwtch.ElapsedMilliseconds);
助けていただけますか?
更新:
スレッド数の増加に伴うほぼ直線的な速度低下の奇妙な動作は、IDE のデバッガーの多数のフックによるアーティファクトのようです。
開発者環境の外でプロセスを実行すると、実際に 2 つの論理/物理コア マシンで 30% の速度向上が得られます。デバッグ中、私はすでに CPU 使用率の上限に達しているため、アイドル コアを追加することで、開発中にある程度の余裕を持たせることが賢明であると思われます。
最初と同じように、各スレッドに独自のローカル データ チャンクで計算させます。このローカル データ チャンクはロックされ、共有リストに書き戻され、すべてのスレッドが終了した後に集計されます。
結論:
プロセスが実行されている環境に注意してください。