【问题标题】:To set the affinity of CPUs using C#使用 C# 设置 CPU 的亲和性
【发布时间】:2012-12-12 07:07:57
【问题描述】:

我在 C# 中创建了一个窗口应用程序。现在我想为这个应用程序设置 CPU 亲和性。我可能有 2 个处理器、4 个处理器、8 个处理器或超过 8 个处理器。

我想使用来自接口的输入来设置 cpu 亲和性。

我怎样才能做到这一点?如何使用 Environment.ProcessorCount 设置亲和力?

【问题讨论】:

  • 不要。操作系统更了解正在发生的事情,相信它会安排您的应用程序和线程。
  • 为什么要设置 CPU 亲和性?你想达到什么目的?如果要避免缓存失效,TPL、PLINQ,甚至简单的线程都有自己的方法来防止处理器之间的数据移动。如果你想限制资源消耗,有比将关联设置到某个(可能超额订阅的)CPU 更有效的方法

标签: c# .net cpu affinity


【解决方案1】:

试试这个:

Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)2;

Here 的更多信息。

ProcessorAffinity 将每个处理器表示为一个位。位 0 代表处理器 1,位 1 代表处理器 2,依此类推。下表显示了四处理器系统可能的 ProcessorAffinity 子集。

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

这是一个小示例程序:

//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);
    }
}

【讨论】:

  • 这个我试过了,但是当我在任务栏中查看时,我发现只有CPU 1被选中。
  • 感谢您的回答并明白了您的意思。我可以不根据 Environment.ProcessorCount 设置亲和力吗?
  • 我修复了newAffinity = newAffinity | int.Parse(item);
  • 使用这个,即使选择1,2,3,4,5也只会选择前3个核心?
【解决方案2】:

Alex Filipovivi 提供的示例程序似乎不正确,因为它将处理器编号 OR 到 newAffinity 中,而没有先将它们转换为设置位。 所以如果你在这个程序中输入 3,4,你会得到一个 7 的关联掩码,即核心 1、2 和 3!掩码应设置为 12(十六进制 0xC,二进制 1100,如果位 0 是最低有效位,则设置位 2 和位 3)。

更换

newAffinity = NewAffinity | int.Parse(item);

newAffinity = newAffinity | (1 << int.Parse(item)-1);

这是一种合理的方法。

【讨论】:

  • 或者你可以认为proc 1、2、3、4是1、2、4、8(2的幂),那么proc 3和4的亲和度是affinitiy = 4 | 8和1, 4 和 7 是affinity = 1 | 8 | 64
【解决方案3】:

适用于寻找线程亲和力的人。

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.");
        }
    }
}

【讨论】:

    【解决方案4】:

    System.Diagnostics.Process.ProcessorAffinity

    你想用Environment.ProcessorCount 做什么?用户输入验证? 无论如何,如果您想选择特定的处理器(#1 或 #2 或 #3...),请创建一个这样的位掩码:

    if (userSelection <= 0 || userSelection > Environment.ProcessorCount)
    {
        throw new ArgumentOutOfRangeException();
    }
    
    int bitMask = 1 << (userSelection - 1);
    Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)bitMask;
    

    其中 userSelection - 是选定处理器的数量。

    如果您想选择多个处理器,那么就这样做

    bitMask |= 1 << (anotherUserSelection - 1);
    

    针对每个用户选择

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 2010-11-27
      • 1970-01-01
      • 2012-01-09
      • 2018-05-19
      相关资源
      最近更新 更多