2

ユーザーのPCの論理コアの数に応じて、さまざまなプロセスにワークロードを割り当てる必要があります。ワークロードは次のコードで実行されます。

static void work()
{
    WorkData myData = new WorkData();
    Worker myWorker = new Worker(myData);
    MyWorker.doWork()
}

私はこのコードで論理コアを数えます:

int nbProcessors = 1;
foreach (var item in new System.Management.ManagementObjectSearcher("Select *  from Win32_ComputerSystem").Get())
{
    nbProcessors = Convert.ToInt32(item["NumberOfLogicalProcessors"]);
}

今、私は論理コアで作業を共有することによって、work()を10000回実行する必要があります。したがって、私のPCの場合、それぞれ1250回のwork()の反復で8つのプロセスを開始することを意味します。また、競合が発生しないように、各プロセスに独自のデータが必要です。

どうやってやるの?

4

5 に答える 5

2

ParallelメソッドとThreadPoolメソッドを確認する必要があると思います。
このクラスはどちらも現在のワークステーション構成に依存しているため、タスクに簡単に使用できます。

並列使用の例:

並列ループ:

int n = 10 000;
Parallel.For(0, n, (i, loopState) =>
{
  // ... 
  if (/* stopping condition is true */)
  {
    loopState.Break();
    return;   
  }
});

スレッド プールのタスク指向の例:

public void DoWork()
{
    // Queue a task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(SomeLongTask));
    // Queue another task.
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(AnotherLongTask));
}

private void SomeLongTask(Object state)
{
    // Insert code to perform a long task.
}

private void AnotherLongTask(Object state)
{
    // Insert code to perform a long task.
}

コメントからの更新:

Task Parallel Library (Parralel クラス) は内部で Threading.Tasks 名前空間を使用し、いくつかのプロセスで以下を管理します。

ThreadPool でのスレッドのスケジューリング

Task ParallelismData Parallelismに関する 2 つの別のリンク。2 番目のリンクは、データの作業のバランスを取るのに役立つと思います。

ワークロードが不均衡になった場合、可能な場合、スケジューラは複数のスレッドとプロセッサ間で作業を再分配します。

于 2012-11-16T10:01:39.120 に答える
2

C# 4.0 以降、 Task Parallel Libraryを使用できるようになり、負荷分散が自動的に行われます。

Parallel.For(0, 10000, p => work());

また

ParallelEnumerable.Range(0, 10000).ForAll(p => work());

参照: .NET Framework での並列プログラミング

于 2012-11-16T10:04:08.017 に答える
1

TPLを見てください:

   Parallel.For (0,10000, item => {
       WorkData myData = new WorkData();
       Worker myWorker = new Worker(myData);
       MyWorker.doWork()
   });

コア間で自動的に分割されます。ただし、必要に応じて、スレッドの数を手動で設定できます

于 2012-11-16T10:00:50.843 に答える
1

うーん、プロパティにアクセスすることで論理プロセッサ数を取得できることをご存知ですか。

Environment.ProcessorCount

私のクアッドコア HT マシンでは 8 が返されます。

固定数の反復がある場合 (たとえば、リストまたは何かに対する反復を行う代わりに)、次を使用できます。

var parallelOptions = new ParallelOptions
{
    MaxDegreeOfParallelistm = Environment.ProcessorCount
};


//edited per comment
Parallel.For(0, 10000, parallelOptions, () =>
{
    WorkData myData = new WorkData();
    Worker myWorker = new Worker(myData);
    MyWorker.doWork() 
});

リストのパーティショニングを行う必要がある場合は、パーティショナーが役立ちます。

var partitioner = Partitioner.Create(yourList);
var parallelOptions = new ParallelOptions
{
    MaxDegreeOfParallelism = Environment.ProcessorCount
};

Parallel.ForEach(partitioner, parallelOptions, (listItem, loopState) =>
{
   //Do something
}

私の知る限り、Parallelループはデフォルトでコアと同じ数のスレッドを生成することに注意してください。

于 2012-11-16T10:03:35.627 に答える
0

こちらのスレッドガイドをご覧ください。
非常に基本的なスレッドから並列プログラミングまで、非常にわかりやすい方法で学習できます。
一言で言えば、本 c# 4.0 の 5 つの章です。
個人的には、スレッド化をよりよく理解するのに大いに役立ちました。

于 2012-11-16T10:43:40.323 に答える