1

4 つのタスクを作成する for ループがあり、各タスクはそのループ インデックスを出力します - パフォーマンスをテストするための簡単なプログラム

上記のループを 1000 回 (反復) 実行する外部ループがあります。TASK とスレッドのパフォーマンスを確認したかったのです。

(1) テスト 1: これは TASK (スレッドではなく) のみを作成すると思っていましたが、TPL を使用していることがわかりました

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));

(2) TaskCreationOptions.LongRunning で次のように書き直しました

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp), TaskCreationOptions.LongRunning);

(3)次に、上記と同じコードを使用してタスクではなくスレッドをテストしようとしましたが、現在はファクトリの代わりに「新しいスレッド」を使用しています

for (int i = 0; i < 4; i++)
{
    var tmp = i;
    tasks[i] = new Thread(new ThreadStart(() => Console.WriteLine(tmp)));
    tasks[i].Start();
    tasks[i].Join();
}

タイミングの結果は、(2)、(3)、(1) の順で最高のパフォーマンスを示しました。

パフォーマンス結果の理由を説明し、上記のどれが本当に単なるタスク (OS プロセス) で、どれがスレッドを使用しているか説明してください。

プロファイラーを使用しようとしましたが、Visual Studio 2010 Professional にしかアクセスできず、プロファイラーには permium または Ultimate バージョンしか付属していないようです。

4

2 に答える 2

0

Console.WriteLineこの場合、パフォーマンスをテストするためのアクションとして使用しても意味がありません。すべてのケースの内部では、反復ごとにプールから新しいスレッドが生成または再利用されます。これは、比較的コストのかかる作業です。つまり、操作が自明である限り、スレッドの生成または再利用コストのオーバーヘッドは常にパフォーマンス テストを大きく損なうことになります。

また、スレッドで実際の重要な操作が行われている場合、ケース間のスポーン コストの違いはもはや問題になりません。Taskそれに加えて、いつ新しいスレッドが作成されるか、プールからのスレッドが再利用されるかを使用するときに、ほとんど制御できません。これは常に良いことです。私のアドバイスは、Tasksバックグラウンドで何かを処理する必要があり、頭痛の種をフレームワークに任せる必要がある場合に使用することです。

これが理解できることを願っています。

また、実用的な目的で、計算する対象の大きなリストがあり、マルチコア CPU を利用したい場合は、Parallel.ForeachまたはTPL.

編集:Parallel.Foreachそして同類は、新しいスレッドをいつ生成するかを自分で決定します。このメソッドを使用すると、プロセッサ数、リストのサイズなどに応じてランタイムが決定するため、最大限の柔軟性が得られます。新しいスレッドを作成することが理にかなっているのか、またはオーバーヘッドがゲインとして大きくなるかどうか。

于 2013-01-29T21:36:30.590 に答える