To set the affinity of CPUs using C#
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);
}
}
Set processor affinity for current thread on Mono (Linux)
lupus's answer was on the right track, but it took me some further research to get this implemented (such as the P/Invoke signature for sched_setaffinity
and the resolution of libc.so.6
). Here's the working code (excluding error-handling) in case anyone needs it:
[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(int pid, IntPtr cpusetsize,
ref ulong cpuset);
private static void SetAffinity(int processorID)
{
ulong processorMask = 1UL << processorID;
sched_setaffinity(0, new IntPtr(sizeof(ulong)), ref processorMask);
}
Edit: The above signature worked fine for my experiments, but refer to David Heffernan's answer (under my other question) for a suggested correction.
C# Change affinity of an application
Just as an extension to answer by @Rowan Smith, there is an additional way of writing binary numbers in C# 7.0 and higher - binary literals.
To specify hex literal one writes 0x
at the beginning of number. For binary literals one should write 0b
like this:
0b0000_0000_0000_0001 -> 1
0b0000_0000_0000_0010 -> 2
0b0000_0000_0000_1111 -> 1 & 2 & 3 4
You write them like:
int value = 0b0000_0000_0000_0001;
Some people might find it easier to write it like this instead of recalculating number between hex and binary representation, although the number itself is longer.
Target specific CPU Cores with Task Parallel Library in .NET?
This kind of micro-optimisation at runtime is way outside the scope of C#. And it should definitely not be hardcoded into the programm itself. Generally the load balancing features of .NET and the OS will deal with running threads efficiently.
With this kind of difference, the speed rant might apply: https://ericlippert.com/2012/12/17/performance-rant/
You can however set up such limits in the OS, without even looking at the applications code: https://www.techjunkie.com/restrict-apps-cpu-cores-processor-affinity/
This sounds more like what you need/should be using.
Is Core Affinity Something that We Can Safely Do in .NET?
No.
.NET threads do not map 1:1 to operating system threads. Thread affinity is for operating system threads. Since the runtime can switch .NET threads between OS threads at will, setting processor affinity will do nothing at best, and waste performance in a typical multi-threaded scenario.
Note that ProcessThread
simply contains information about running operating system thread in a process. It's just what you get when you ask what threads a process has - it's part of the OS, not .NET. In contrast, Thread
is about your threads, and only the managed ones.
Related Topics
How to Write a JSON File in C#
Printing All Contents of Array in C#
Windows Like Services Development in Linux Using Mono
Reference Assemblies for Framework ".Netframework,Version=V4.7.1" Were Not Found
Distinct by Property of Class with Linq
Is There a Way of Setting Culture for a Whole Application? All Current Threads and New Threads
Run Async Method Regularly with Specified Interval
How to I Catch Ssl Exceptions in a Mono Httplistener Server
How to Get Object Size in Memory
Using String Format to Show Decimal Up to 2 Places or Simple Integer
Differencebetween an Int and an Integer in Java and C#
C# VS Java Enum (For Those New to C#)
How to Get and Set Environment Variables in C#
How to Set Cursor Position in Gtk -Linux, Monodevelop
How to Access a Variable from Another Script in Another Gameobject Through Getcomponent