有没有办法通过.NET/C#找到CPU内核的数量?

PS这是一个直接的代码问题,而不是"我应该使用多线程吗?"问题!:-)

推荐答案

您可以获得与处理器相关的几种不同信息:

  1. 物理处理器数量
  2. 核心数量
  3. 逻辑处理器的数量.

这些都可能是不同的;如果机器有两个双核支持超线程的处理器,则有两个物理处理器、4个内核和8个逻辑处理器.

逻辑处理器的数量可以通过Environment类获得,但其他信息只能通过WMI获得(您可能需要安装大约hotfixes or service packs个才能在某些系统上获得):

Make sure to add a reference in your project to System.Management.dll

Physical Processors:

foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
    Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);
}

Cores:

int coreCount = 0;
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
{
    coreCount += int.Parse(item["NumberOfCores"].ToString());
}
Console.WriteLine("Number Of Cores: {0}", coreCount);

Logical Processors:

Console.WriteLine("Number Of Logical Processors: {0}", Environment.ProcessorCount);

foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
    Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);
}

Processors excluded from Windows:

您还可以在setupapi.dll中使用Windows API调用来发现已被排除在Windows之外(例如通过 bootstrap 设置)且使用上述方法无法检测到的处理器.下面的代码给出了现有的逻辑处理器总数(我还没有弄清楚如何区分物理处理器和逻辑处理器),包括那些被排除在Windows之外的处理器:

static void Main(string[] args)
{
    int deviceCount = 0;
    IntPtr deviceList = IntPtr.Zero;
    // GUID for processor classid
    Guid processorGuid = new Guid("{50127dc3-0f36-415e-a6cc-4cb3be910b65}");

    try
    {
        // get a list of all processor devices
        deviceList = SetupDiGetClassDevs(ref processorGuid, "ACPI", IntPtr.Zero, (int)DIGCF.PRESENT);
        // attempt to process each item in the list
        for (int deviceNumber = 0; ; deviceNumber++)
        {
            SP_DEVINFO_DATA deviceInfo = new SP_DEVINFO_DATA();
            deviceInfo.cbSize = Marshal.SizeOf(deviceInfo);

            // attempt to read the device info from the list, if this fails, we're at the end of the list
            if (!SetupDiEnumDeviceInfo(deviceList, deviceNumber, ref deviceInfo))
            {
                deviceCount = deviceNumber;
                break;
            }
        }
    }
    finally
    {
        if (deviceList != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceList); }
    }
    Console.WriteLine("核心数量: {0}", deviceCount);
}

[DllImport("setupapi.dll", SetLastError = true)]
private static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid,
    [MarshalAs(UnmanagedType.LPStr)]String enumerator,
    IntPtr hwndParent,
    Int32 Flags);

[DllImport("setupapi.dll", SetLastError = true)]
private static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet,
    Int32 MemberIndex,
    ref SP_DEVINFO_DATA DeviceInterfaceData);

[StructLayout(LayoutKind.Sequential)]
private struct SP_DEVINFO_DATA
{
    public int cbSize;
    public Guid ClassGuid;
    public uint DevInst;
    public IntPtr Reserved;
}

private enum DIGCF
{
    DEFAULT = 0x1,
    PRESENT = 0x2,
    ALLCLASSES = 0x4,
    PROFILE = 0x8,
    DEVICEINTERFACE = 0x10,
}

.net相关问答推荐

Azure Function应用程序-如何升级.NET运行时

.NET Core 中的微服务

在 C# 中,如何使用泛型的基类将泛型接口的所有实例注入到单个构造函数中?

如何在 Windows 窗体上显示 ClickOnce 版本号

在 C# 中输入按键

单击关闭按钮时隐藏表单而不是关闭

为什么 SortedSet.GetViewBetween 不是 O(log N)?

编译时禁用 Dll 文化文件夹

将 BitmapImage 转换为 Bitmap,反之亦然

C# 是否(或将)包含用于副作用验证的功能?

我应该默认推荐密封类吗?

如何从 appsettings.json 中获取价值

如何从字符串中删除所有字母字符?

Int 到字节数组

如何在 C# 7 中返回多个值?

.NET 如何判断路径是否是文件而不是目录?

寻找 .NET 的命令行参数解析器

为什么使用 ImmutableList 而不是 ReadOnlyCollection?

react 式扩展使用的好例子

如何重新启动 WPF 应用程序?