To do this requires breaking down several layers of abstraction and before doing it I would recommend doing quite a bit of profiling to be certain that doing this will be better performance than letting the framework handle resource allocation. I am somewhat doubtful (though I can't say I've analyzed it).
The first thing you need to do is to make sure that your two Task
s get executed on different managed threads. Because this is trying to assert manual control over something the framework handles, to be certain that this is the case you would need to write your own TaskScheduler
. However, realistically you can do this by specifying the TaskCreationOptions.LongRunning
flag. On the current desktop CLR, at least, that will always create a new thread. But it's just a hint, API-wise.
The next abstraction to break is that of managed vs native threads. Each of your methods should be wrapped in a thread affinity block. The framework is allowed to switch the physical thread a managed thread is running on. Since processor affinity is a native thread operation, you have to tell the framework not to do that.
Next, you need to get the native thread that corresponds to the current managed thread. In each method, after calling BeginThreadAffinity
, get the native thread by calling GetCurrentThreadId via p/invoke.
Now you can do the rest of this in either native or managed land, but I'll assume you want to do it in .NET. In that case, get the ProcessThread object which corresponds to the native thread, and you can set processor affinity or ideal processor from there:
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()