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