C / C++ provide for a way to set the number of OMP threads, but I'm wondering if C# has a similar functionality.
Basically, my use case is that I've got an external executable that brings every core up to 100% usage when it runs. I'd like to test if the application performs any better if it was using one core at a time. On my windows machine, I did run the command set OMP_NUM_THREADS=1 and saw that the executable ran in a comparable time, but on only 1 core instead, as expected.
I have a C# test program that can spawn N multiple threads which each run a copy of the executable. I'd like to be able to run each of those threads with OMP_NUM_THREADS set to one, with the hope that only N of my cpu cores go up to full usage.
Note: I'm using the System.Diagnostics Process class to run my process through separate threads.
I was able to arrive at a solution that worked for me, thanks to the various links Robert Harvey posted above. The link most helpful to me was http://blog.rebuildall.net/2010/03/08/Running_NET_threads_on_selected_processor_cores.
int affinity = 1; // needs to be greater than 0
string parameters = string.Format("{0} {1} {2}", cmdLineParam1, cmdLineParam2, cmdLineParam3);
Process process = new Process();
process.StartInfo = new ProcessStartInfo()
{
Arguments = parameters,
CreateNoWindow = true,
FileName = pathToExe,
WindowStyle = ProcessWindowStyle.Hidden
};
process.Start();
try
{
// try to run this process on one dedicated CPU
if (affinity > 0)
process.ProcessorAffinity = new IntPtr(affinity);
}
catch (Exception e)
{
Console.WriteLine("Could not set process affinity: {0}", e.Message);
}
// limit run-time of the process
if (process.WaitForExit(90000) == false)
{
process.Kill();
Console.WriteLine("Process has ran longer than 90 seconds, timing it out now.");
}
Note that if you run this code across multiple threads, like I am doing, you will need to set a separate affinity for each thread, so that they'll use different CPU cores.
Also note that affinity is a bitmask...This means that the number 3 indicates that a process should run on CPU cores 1 and 2, not core 3. to help with generating the bitmask, I wrote the code below:
public static int GetProcessorBitMask(int numProcessors, int startingProcessor)
{
Console.WriteLine("numProcessors: {0} | startingProcessor: {1}", numProcessors, startingProcessor);
int mask = (int) Math.Pow(2, numProcessors) - 1;
mask <<= (startingProcessor - 1);
return mask;
}