I have created a window application in C#.Now I want to set the CPU affinity for this application.I may have 2 processors,4 processors,8 processors or may be more than 8 process
For people looking for thread affinity.
public class CpuAffinity
{
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
[DllImport("kernel32.dll")]
static extern IntPtr SetThreadAffinityMask(IntPtr hThread, IntPtr dwThreadAffinityMask);
/// <summary>
/// Sets the current Thread to have affinity to the specified cpu/processor if the system has more than one.
///
/// Supports most systems as we use a signed int; Anything more than 31 CPU's will not be supported.
/// </summary>
/// <param name="cpu">The index of CPU to set.</param>
public static void SetCurrentThreadToHaveCpuAffinityFor(int cpu)
{
if (cpu < 0)
{
throw new ArgumentOutOfRangeException("cpu");
}
if (Environment.ProcessorCount > 1)
{
var ptr = GetCurrentThread();
SetThreadAffinityMask(ptr, new IntPtr(1 << cpu));
Debug.WriteLine("Current Thread Of OS Id '{0}' Affinity Set for CPU #{1}.", ptr, cpu);
}else
{
Debug.WriteLine("The System only has one Processor. It is impossible to set CPU affinity for other CPU's that do not exist.");
}
}
}
The provided sample program by Alex Filipovivi seems incorrect, in that it ORs processor numbers into newAffinity without first converting them into a set bit. So if you input 3,4 to this program, you get an affinity mask of 7, which is cores 1, 2, and 3! The mask should be set to 12 (hex 0xC, binary 1100, which has bits 2 and 3 set, if bit 0 is the least significant bit).
Replacing
newAffinity = NewAffinity | int.Parse(item);
with
newAffinity = newAffinity | (1 << int.Parse(item)-1);
Is one reasonable way to do that.
Try this:
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)2;
Here's more about it.
ProcessorAffinity represents each processor as a bit. Bit 0 represents processor one, bit 1 represents processor two, and so on. The following table shows a subset of the possible ProcessorAffinity for a four-processor system.
Property value (in hexadecimal) Valid processors
0x0001 1
0x0002 2
0x0003 1 or 2
0x0004 3
0x0005 1 or 3
0x0007 1, 2, or 3
0x000F 1, 2, 3, or 4
Here's a small sample program:
//TODO: manage exceptions
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Total # of processors: {0}", Environment.ProcessorCount);
Console.WriteLine("Current processor affinity: {0}", Process.GetCurrentProcess().ProcessorAffinity);
Console.WriteLine("*********************************");
Console.WriteLine("Insert your selected processors, separated by comma (first CPU index is 1):");
var input = Console.ReadLine();
Console.WriteLine("*********************************");
var usedProcessors = input.Split(',');
//TODO: validate input
int newAffinity = 0;
foreach (var item in usedProcessors)
{
newAffinity = newAffinity | int.Parse(item);
Console.WriteLine("Processor #{0} was selected for affinity.", item);
}
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)newAffinity;
Console.WriteLine("*********************************");
Console.WriteLine("Current processor affinity is {0}", Process.GetCurrentProcess().ProcessorAffinity);
}
}
System.Diagnostics.Process.ProcessorAffinity
What do you want to use Environment.ProcessorCount
for? User input validation?
Anyway if you want to select a particular processor (#1 or #2 or #3...), create a bitmask like that:
if (userSelection <= 0 || userSelection > Environment.ProcessorCount)
{
throw new ArgumentOutOfRangeException();
}
int bitMask = 1 << (userSelection - 1);
Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)bitMask;
Where userSelection - is a number of selected processor.
If you'd like to select more than one processor, then do
bitMask |= 1 << (anotherUserSelection - 1);
for each user selection