0

7 つのコアを使用する (または 1 つのコアから離れる) には並列 for ループの反復が必要ですが、8 つの (すべての) コアを使用するために別の反復が必要で、以下のコードを試しました:

Parallel.For(0,2,i=>{
  if(i=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(i==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});

これは、両方の反復で 255 を出力します。したがって、parallel.for ループが単一のスレッドを使用しているか、1 つの設定で他の反復アフィニティも設定されています。もう 1 つの問題は、これは遅延の影響を受けやすいアプリケーションによるものであり、このすべてのアフィニティ設定によって 1 ~ 15 ミリ秒の遅延が追加されることです。

スレッドを明示的に使用する必要がありますか? また、アフィニティは 1 回だけ設定する必要がありますか?

編集:スレッドバージョンを試しましたが、同じことが起こります。明示的な 2 つのスレッドでも、両方とも 255 をコンソールに書き込みます。現在、このコマンドはスレッドではなくプロセス用のようです。

OpenCL コンテキストは、1 回の反復で CPU でのカーネル実行に最大コア数を使用しています。1 ~ 2 個のコアを使用してバッファーをコピーし、コマンドをデバイスに送信するその他の反復。cpu が opencl によって使用される場合、すべてのコアが使用され、デバイスはバッファーをコピーするのに十分な時間を確保できません。デバイスの分裂は、この問題を解決するよりも難しいようです。

4

1 に答える 1

2

Parallel.For Iterations の異なるスレッド アフィニティ

ParallelAPIが複数のスレッドを意味するという仮定に基づいているため、質問は誤解を招きます。ParallelAPI は Data Parallel 処理を指しますがmultiple threads、特に上記のコードでは、スレッドごとの作業がほとんどないため、 の呼び出しを保証するものではありません。

API の場合Parallel、次のように最大並列度を設定できます。

ParallelOptions parallelOption = new ParallelOptions();

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;

Parallel.For(0, 20, parallelOption, i =>

ただし、並列処理に呼び出されるスレッドの数は保証されません。スレッドは から使用され、処理する作業の量に基づいて、処理に必要な数を超えるかどうかを実行時に決定するThreadPoolためです。CLRone thread

同じParallelループで次の print を試すことができますThread.Current.ManageThreadId。これにより、ループで呼び出されるスレッドの数に関して明確なアイデアが得られParallelます。

スレッドを明示的に使用する必要がありますか? また、アフィニティは 1 回だけ設定する必要がありますか?

編集:スレッドバージョンを試しましたが、同じことが起こります。明示的な 2 つのスレッドでも、両方とも 255 をコンソールに書き込みます。現在、このコマンドはスレッドではなくプロセス用のようです。

複数のスレッドのコードを投稿できますか、このようなことを試すことができますか。

Thread[] threadArray = new Thread[2];
threadArray[0] = new Thread(<ThreadDelegate>);
threadArray[1] = new Thread(<ThreadDelegate>);
threadArray[0]. ProcessorAffinity = <Set Processor Affinity>
threadArray[1]. ProcessorAffinity = <Set Processor Affinity>

アフィニティを正しく割り当てたと仮定すると、それらを出力してさまざまな値を見つけることができます。次のProcessThread.ProcessorAffinityを確認してください。

上記のリンクでわかるように、hexadecimalプロセッサのアフィニティに基づいて値を設定できますが、値が何を意味するかわからない場合254, 255は、実際にその数のプロセッサを搭載したサーバーを持っているかどうかを確認してください。

編集:

プログラムに次の編集を試してみてください (2 つのスレッド ID が出力されているという事実に基づいて)、両方のスレッドが画像に含まれるまでに、両方とも同じ値の を取得します。閉鎖の問題を回避するためvariable iに が必要です。local variable

Parallel.For(0,2,i=>{
  int local = i;
  if(local=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(local==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});

EDIT 2:(実際のロジック実行前に、両方のスレッドがインクリメントする可能性があるため、ほとんど機能しません)

 int local = -1;
  Parallel.For(0,2,i=>{
  Interlocked.Increment(ref local);
  if(local=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(local==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});
于 2016-09-16T05:22:51.507 に答える