Как найти количество ядер процессора через .NET / C #?

Есть ли способ через .NET / C #, чтобы узнать количество ядер процессора?

PS Это вопрос с прямым кодом, а не «Должен ли я использовать multithreading?» вопрос! 🙂

    10 Solutions collect form web for “Как найти количество ядер процессора через .NET / C #?”

    Существует несколько различных частей информации, относящихся к процессорам, которые вы можете получить:

    1. Количество физических процессоров
    2. Количество ядер
    3. Количество логических процессоров.

    Все они могут быть разными; в случае машины с двумя двухъядерными процессорами с поддержкой гиперstreamов, имеется 2 физических процессора, 4 ядра и 8 логических процессоров.

    Количество логических процессоров доступно через class среды , но другая информация доступна только через WMI (и вам может потребоваться установить некоторые исправления или пакеты обновления, чтобы получить их в некоторых системах):

    Не забудьте добавить ссылку в свой проект в System.Management.dll

    Физические процессоры:

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

    Ядра:

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

    Логические процессоры:

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

    Процессоры, исключенные из Windows:

    Вы также можете использовать вызовы Windows API в файле setupapi.dll для обнаружения процессоров, которые были исключены из Windows (например, через настройки загрузки) и не могут быть обнаружены с использованием вышеуказанных средств. В приведенном ниже коде содержится общее количество логических процессоров (я не мог определить, как отличать физические от логических процессоров), которые существуют, в том числе те, которые были исключены из 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 - 1; break; } } } finally { if (deviceList != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceList); } } Console.WriteLine("Number of cores: {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, } 
     Environment.ProcessorCount 

    [Документация]

    Запросы WMI медленны, поэтому попробуйте выбрать только нужные члены, а не использовать Select *.

    Следующий запрос принимает 3.4s:

     foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) 

    Пока этот занимает 0.122s:

     foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get()) 

    Environment.ProcessorCount должен предоставить вам количество ядер на локальной машине.

    Интересно посмотреть, как .NET получает это внутренне, чтобы сказать наименьшее … Это как «просто», как показано ниже:

     namespace System.Threading { using System; using System.Runtime.CompilerServices; internal static class PlatformHelper { private const int PROCESSOR_COUNT_REFRESH_INTERVAL_MS = 0x7530; private static volatile int s_lastProcessorCountRefreshTicks; private static volatile int s_processorCount; internal static bool IsSingleProcessor { get { return (ProcessorCount == 1); } } internal static int ProcessorCount { get { int tickCount = Environment.TickCount; int num2 = s_processorCount; if ((num2 == 0) || ((tickCount - s_lastProcessorCountRefreshTicks) >= 0x7530)) { s_processorCount = num2 = Environment.ProcessorCount; s_lastProcessorCountRefreshTicks = tickCount; } return num2; } } } } 

    Из источника .NET Framework

    Вы также можете получить его с помощью PInvoke на Kernel32.dll

    Следующий код поступает более или менее из SystemInfo.cs из источника System.Web, расположенного здесь :

     [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SYSTEM_INFO { public ushort wProcessorArchitecture; public ushort wReserved; public uint dwPageSize; public IntPtr lpMinimumApplicationAddress; public IntPtr lpMaximumApplicationAddress; public IntPtr dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public ushort wProcessorLevel; public ushort wProcessorRevision; } internal static class SystemInfo { internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] internal static extern void GetSystemInfo(out SYSTEM_INFO si); [DllImport("kernel32.dll")] internal static extern int GetProcessAffinityMask(IntPtr handle, out IntPtr processAffinityMask, out IntPtr systemAffinityMask); internal static int GetNumProcessCPUs() { if (SystemInfo._trueNumberOfProcessors == 0) { SYSTEM_INFO si; GetSystemInfo(out si); if ((int) si.dwNumberOfProcessors == 1) { SystemInfo._trueNumberOfProcessors = 1; } else { IntPtr processAffinityMask; IntPtr systemAffinityMask; if (GetProcessAffinityMask(INVALID_HANDLE_VALUE, out processAffinityMask, out systemAffinityMask) == 0) { SystemInfo._trueNumberOfProcessors = 1; } else { int num1 = 0; if (IntPtr.Size == 4) { uint num2 = (uint) (int) processAffinityMask; while ((int) num2 != 0) { if (((int) num2 & 1) == 1) ++num1; num2 >>= 1; } } else { ulong num2 = (ulong) (long) processAffinityMask; while ((long) num2 != 0L) { if (((long) num2 & 1L) == 1L) ++num1; num2 >>= 1; } } SystemInfo._trueNumberOfProcessors = num1; } } } return SystemInfo._trueNumberOfProcessors; } } 

    Самый простой способ = Environment.ProcessorCount Exemple from Environment.ProcessorCount Свойство

      using System; class Sample { public static void Main() { Console.WriteLine("The number of processors " + "on this computer is {0}.", Environment.ProcessorCount); } } 

    Один из вариантов – прочитать данные из реестра. Статья MSDN по теме: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx )

    Процессоры, я считаю, могут быть расположены здесь, HKEY_LOCAL_MACHINE \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor

      private void determineNumberOfProcessCores() { RegistryKey rk = Registry.LocalMachine; String[] subKeys = rk.OpenSubKey("HARDWARE").OpenSubKey("DESCRIPTION").OpenSubKey("System").OpenSubKey("CentralProcessor").GetSubKeyNames(); textBox1.Text = "Total number of cores:" + subKeys.Length.ToString(); } 

    Я достаточно уверен, что запись в реестре будет присутствовать в большинстве систем.

    Хотя я бы бросил свои $ 0,02 дюйма.

    Следующая программа печатает логические и физические ядра машины Windows.

     #define STRICT #include "stdafx.h" #include  #include  #include  template T *AdvanceBytes(T *p, SIZE_T cb) { return reinterpret_cast(reinterpret_cast(p) + cb); } class EnumLogicalProcessorInformation { public: EnumLogicalProcessorInformation(LOGICAL_PROCESSOR_RELATIONSHIP Relationship) : m_pinfoBase(nullptr), m_pinfoCurrent(nullptr), m_cbRemaining(0) { DWORD cb = 0; if (GetLogicalProcessorInformationEx(Relationship, nullptr, &cb)) return; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return; m_pinfoBase = reinterpret_cast (LocalAlloc(LMEM_FIXED, cb)); if (!m_pinfoBase) return; if (!GetLogicalProcessorInformationEx(Relationship, m_pinfoBase, &cb)) return; m_pinfoCurrent = m_pinfoBase; m_cbRemaining = cb; } ~EnumLogicalProcessorInformation() { LocalFree(m_pinfoBase); } void MoveNext() { if (m_pinfoCurrent) { m_cbRemaining -= m_pinfoCurrent->Size; if (m_cbRemaining) { m_pinfoCurrent = AdvanceBytes(m_pinfoCurrent, m_pinfoCurrent->Size); } else { m_pinfoCurrent = nullptr; } } } SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *Current() { return m_pinfoCurrent; } private: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *m_pinfoBase; SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *m_pinfoCurrent; DWORD m_cbRemaining; }; int __cdecl main(int argc, char **argv) { int numLogicalCore = 0; int numPhysicalCore = 0; for (EnumLogicalProcessorInformation enumInfo(RelationProcessorCore); auto pinfo = enumInfo.Current(); enumInfo.MoveNext()) { int numThreadPerCore = (pinfo->Processor.Flags == LTP_PC_SMT) ? 2 : 1; // std::cout < < "thread per core: "<< numThreadPerCore << std::endl; numLogicalCore += numThreadPerCore; numPhysicalCore += 1; } printf ("Number of physical core = %d , Number of Logical core = %d \n", numPhysicalCore, numLogicalCore ); char c = getchar(); /* just to wait on to see the results in the command prompt */ return 0; } /* I tested with Intel Xeon four cores with hyper threading and here is the result Number of physical core = 4 , Number of Logical core = 8 */ 

    Я искал то же самое, но я не хочу устанавливать какой-либо nuget или servicepack, поэтому я нашел это решение, это довольно просто и прямолинейно, используя эту дискуссию, я подумал, что было бы так легко запустить эту команду WMIC и получить это значение, вот код C #. Вам нужно всего лишь использовать пространство имен System.Management (и пару более стандартных пространств имен для процесса и т. Д.).

      string fileName = Path.Combine(Environment.SystemDirectory, "wbem", "wmic.exe"); string arguments = @"cpu get NumberOfCores"; Process process = new Process { StartInfo = { FileName = fileName, Arguments = arguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true } }; process.Start(); StreamReader output = process.StandardOutput; Console.WriteLine(output.ReadToEnd()); process.WaitForExit(); int exitCode = process.ExitCode; process.Close(); 
    Давайте будем гением компьютера.