2

Tpl作業をPlinq 自動的にスレッドに割り当てます(コア/秒で... {まあ、もしそうなら #threads> #cores、>1スレッドが同じコアで実行されます。 })。

MyMethod1(){..}ただし、 と を持っているとしましょう (!) それぞれが異なるコアで実行されることを確認MyMethod2(){..}する必要があります! (例: 集中コンピューティング)

私が見つけた最も近い解決策はPlinq'sです.WithExecutionMode (ParallelExecutionMode.ForceParallelism)

しかし、これは、Plinq が並列ではなく順次実行する方がよいと考える可能性がある別の状況のた​​めのものです。また、私は Plinq を使用しません。別のコアで実行する必要があるメソッドは 2 つしかありません。

どうすればできますか?

psここSOで使用することを提案した回答がありましたがTaskCreationOptions.LongRunning、TaskSchedulerにスレッドプールスレッドをより積極的に作成する必要があることを示唆するだけです。ただし、これらのスレッドは同じコア上にある可能性があります。そして私の状況では、それらが別のコアにある必要がありました。

ありがとうございました。

4

1 に答える 1

8

これを行うには、抽象化のいくつかの層を分解する必要があります。実行する前に、かなりのプロファイリングを行って、フレームワークにリソース割り当てを処理させるよりもパフォーマンスが向上することを確認することをお勧めします。私は少し疑わしいです(分析したとは言えませんが)。

最初に行う必要があるのは、2 つTaskの が異なるマネージ スレッドで実行されるようにすることです。これは、フレームワークが処理するものを手動で制御しようとしているため、これが事実であることを確認するには、独自のTaskScheduler. TaskCreationOptions.LongRunningただし、現実的には、フラグを指定することでこれを行うことができます。少なくとも現在のデスクトップ CLR では、常に新しいスレッドが作成されます。しかし、これは API に関する単なるヒントです。

次に破るべき抽象化は、マネージ スレッドとネイティブ スレッドの抽象化です。各メソッドは、スレッド アフィニティブロックでラップする必要があります。フレームワークは、マネージド スレッドが実行されている物理スレッドを切り替えることができます。プロセッサ アフィニティはネイティブ スレッド操作であるため、フレームワークにそうしないように指示する必要があります。

次に、現在のマネージド スレッドに対応するネイティブ スレッドを取得する必要があります。各メソッドで、 を呼び出した後、 p/invoke 経由でGetCurrentThreadIdBeginThreadAffinityを呼び出してネイティブ スレッドを取得します。

これで残りの作業はネイティブ ランドでもマネージド ランドでも実行できますが、.NET で実行することを想定しています。その場合、ネイティブ スレッドに対応するProcessThreadオブジェクトを取得し、そこからプロセッサ アフィニティまたは理想的なプロセッサを設定できます。

Thread.BeginThreadAffinity();
int threadId = GetCurrentThreadId();
Process proc = Process.GetCurrentProcess();
ProcessThread procThread = proc.Threads.Cast<ProcessThread>().Single(
    pt => pt.Id == threadId
);
procThread.ProcessorAffinity = new IntPtr(0x01);
//
// work
//
procThread.ProcessorAffinity = new IntPtr(0xFFFF);
Thread.EndThreadAffinity()
于 2013-03-30T13:11:27.707 に答える