Created
April 7, 2017 13:34
-
-
Save alexandrnikitin/babfa4781c68f1664d4a81339fe3a0aa to your computer and use it in GitHub Desktop.
How to set processor group affinity in .NET C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ConsoleApp1 | |
{ | |
class Program | |
{ | |
[StructLayout(LayoutKind.Sequential, Pack = 4)] | |
private struct _GROUP_AFFINITY | |
{ | |
public UIntPtr Mask; | |
[MarshalAs(UnmanagedType.U2)] | |
public ushort Group; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U2)] | |
public ushort[] Reserved; | |
} | |
[DllImport("kernel32", SetLastError = true)] | |
private static extern Boolean SetThreadGroupAffinity( | |
IntPtr hThread, | |
ref _GROUP_AFFINITY GroupAffinity, | |
ref _GROUP_AFFINITY PreviousGroupAffinity); | |
[DllImport("kernel32", SetLastError = true)] | |
private static extern IntPtr GetCurrentThread(); | |
/// <summary> | |
/// Sets the processor group and the processor cpu affinity of the current thread. | |
/// </summary> | |
/// <param name="group">A processor group number.</param> | |
/// <param name="cpus">A list of CPU numbers. The values should be | |
/// between 0 and <see cref="Environment.ProcessorCount"/>.</param> | |
public static void SetThreadProcessorAffinity(ushort groupId, params int[] cpus) | |
{ | |
if (cpus == null) throw new ArgumentNullException(nameof(cpus)); | |
if (cpus.Length == 0) throw new ArgumentException("You must specify at least one CPU.", nameof(cpus)); | |
// Supports up to 64 processors | |
long cpuMask = 0; | |
foreach (var cpu in cpus) | |
{ | |
if (cpu < 0 || cpu >= Environment.ProcessorCount) | |
throw new ArgumentException("Invalid CPU number."); | |
cpuMask |= 1L << cpu; | |
} | |
var hThread = GetCurrentThread(); | |
var previousAffinity = new _GROUP_AFFINITY {Reserved = new ushort[3]}; | |
var newAffinity = new _GROUP_AFFINITY | |
{ | |
Group = groupId, | |
Mask = new UIntPtr((ulong) cpuMask), | |
Reserved = new ushort[3] | |
}; | |
SetThreadGroupAffinity(hThread, ref newAffinity, ref previousAffinity); | |
} | |
static void Main(string[] args) | |
{ | |
ushort groupId = 0; | |
var cpuId = 0; | |
if (args != null && args.Length > 0) | |
{ | |
groupId = ushort.Parse(args[0]); | |
cpuId = int.Parse(args[1]); | |
} | |
SetThreadProcessorAffinity(groupId, cpuId); | |
// some calculation to see affinity in action | |
Enumerable.Range(1, Int32.MaxValue).Aggregate((acc, x) => acc * x); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment