Вам нужно знать, сколько ядер или сколько логических процессоров? Возможно, достаточно просто запустить несколько потоков, но есть сценарии, в которых разница может быть важной.
Кевин Киблер
Есть ли более новый способ сделать это?
MoonKnight
Ответы:
477
Есть несколько разных частей информации, касающихся процессоров, которые вы можете получить:
Количество физических процессоров
Количество ядер
Количество логических процессоров.
Все они могут быть разными; в случае машины с двумя двухъядерными процессорами с поддержкой гиперпоточности есть 2 физических процессора, 4 ядра и 8 логических процессоров.
Число логических процессоров доступно через класс Environment , но другая информация доступна только через WMI (и вам может потребоваться установить некоторые исправления или пакеты обновления, чтобы получить его на некоторых системах):
Не забудьте добавить ссылку в вашем проекте в System.Management.dll.
В .NET Core это доступно (только для Windows) в виде пакета NuGet.
Физические процессоры:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()){Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);}
Ядра:
int coreCount =0;foreach(var item innewSystem.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 innewSystem.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()){Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);}
Процессоры исключены из Windows:
Вы также можете использовать вызовы API Windows в файле setupapi.dll, чтобы обнаружить процессоры, которые были исключены из Windows (например, через настройки загрузки) и которые невозможно обнаружить с помощью вышеуказанных средств. Приведенный ниже код дает общее количество существующих логических процессоров (я не смог выяснить, как отличить физические процессоры от логических), включая те, которые были исключены из Windows:
staticvoidMain(string[] args){int deviceCount =0;IntPtr deviceList =IntPtr.Zero;// GUID for processor classidGuid processorGuid =newGuid("{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 listfor(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 listif(!SetupDiEnumDeviceInfo(deviceList, deviceNumber,ref deviceInfo)){
deviceCount = deviceNumber;break;}}}finally{if(deviceList !=IntPtr.Zero){SetupDiDestroyDeviceInfoList(deviceList);}}Console.WriteLine("Number of cores: {0}", deviceCount);}[DllImport("setupapi.dll",SetLastError=true)]privatestaticexternIntPtrSetupDiGetClassDevs(refGuidClassGuid,[MarshalAs(UnmanagedType.LPStr)]String enumerator,IntPtr hwndParent,Int32Flags);[DllImport("setupapi.dll",SetLastError=true)]privatestaticexternInt32SetupDiDestroyDeviceInfoList(IntPtrDeviceInfoSet);[DllImport("setupapi.dll",SetLastError=true)]privatestaticexternboolSetupDiEnumDeviceInfo(IntPtrDeviceInfoSet,Int32MemberIndex,ref SP_DEVINFO_DATA DeviceInterfaceData);[StructLayout(LayoutKind.Sequential)]privatestruct SP_DEVINFO_DATA
{publicint cbSize;publicGuidClassGuid;publicuintDevInst;publicIntPtrReserved;}privateenum DIGCF
{
DEFAULT =0x1,
PRESENT =0x2,
ALLCLASSES =0x4,
PROFILE =0x8,
DEVICEINTERFACE =0x10,}
@StingyJack: Правда, но я бы хотел, чтобы это было в более хорошем формате. Обнаруживаемость довольно низкая, когда вам приходится создавать необработанные строковые запросы.
Кевин Киблер
5
WMI Code Creator поможет с обнаружением значений и созданием запросов (он даже может генерировать заглушки в c # / vb.net).
StingyJack
4
Это в System.Management.dll. Вы включили ссылку на эту сборку в свой проект?
Кевин Киблер
2
Незначительная ошибка в приведенном выше коде. Так deviceCountкак основано на нуле, число ядер должно быть Console.WriteLine("Number of cores: {0}", deviceCount + 1);
выведено
2
Разве вы не вызываете проблемы, не выбрасывая объекты управления и поисковики?
Это так красиво просто, что я почти плачу. Спасибо за ответ!
MrGreggles
70
Это дает количество логических процессоров, а не количество ядер.
Кевин Киблер
8
@KevinKibler Исходя из вопроса, я подозреваю, что ОП не понимает разницу, и если вы не знаете разницу, это, вероятно, то, что вы хотите.
Гленн Мейнард
1
Это также возвращает неправильный счет во многих основных системах. Я использую два основных процессора dodeca с гиперпоточностью, что дает мне в общей сложности 48 логических процессоров. Environment.ProcessorCountдает 32.
Аллен Кларк Коупленд-младший
1
@AlexanderMorou, да, это не даст точных результатов на некоторых многопроцессорных серверах. Существует исправление для этого, но еще не проверял это.
TheLegendaryCopyCoder
35
Запросы WMI медленные, поэтому старайтесь выбирать только нужные элементы вместо использования Select *.
Следующий запрос занимает 3,4 с:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
В то время как этот занимает 0,122 с:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())
На какой системе вы работаете? Я использую несколько «Select *» запросов и не занимает где - нибудь около 3,4 секунды, опробованы на тысячах компьютеров , что мое программное обеспечение развертывается на. Я делаю Select *, потому что я получаю несколько свойств от объекта. Однако я делаю это немного иначе: создаю ObjectQuery на Select *; получить ManagementObjectCollection; затем передайте ManagementObject в ManagementObjectCollection.
Диджи
@deegee: вы правы, сам запрос не занимает много времени с «Select *», просто разбор int ниже медленен при повторении всех возвращаемых значений, а не только NumberOfCores.
using System;classSample{publicstaticvoidMain(){Console.WriteLine("The number of processors "+"on this computer is {0}.",Environment.ProcessorCount);}}
Это даст количество процессоров, которые уже доступны в Environment.ProcessorCount, есть ли другой подобный способ получить количество ядер для каждого процессора?
Армен
0
Следующая программа печатает логическое и физическое ядро машины Windows.
#define STRICT
#include"stdafx.h"#include<windows.h>#include<stdio.h>#include<omp.h>
template<typename T>
T *AdvanceBytes(T *p, SIZE_T cb){return reinterpret_cast<T*>(reinterpret_cast<BYTE *>(p)+ cb);}classEnumLogicalProcessorInformation{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<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>(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);}voidMoveNext(){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 */return0;}/*
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
*/
Этот вопрос помечен .NET; Ваш код не является кодом .NET.
Вай Ха Ли
-1
Я искал то же самое, но я не хочу устанавливать какой-либо nuget или пакет обновления, поэтому я нашел это решение, оно довольно простое и прямолинейное, используя это обсуждение, я подумал, что было бы так легко выполнить эту команду WMIC и получить это значение, вот код C #. Вам нужно только использовать пространство имен System.Management (и пару стандартных пространств имен для процесса и т. Д.).
string fileName =Path.Combine(Environment.SystemDirectory,"wbem","wmic.exe");string arguments =@"cpu get NumberOfCores";Process process =newProcess{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();
Не уверен, почему вы делаете простой запрос WMI таким сложным. Запуск командной строки WMI как внешнего процесса и анализ его выходных данных на самом деле не требуется. .NET имеет встроенную поддержку запросов WMI (System.Management.ManagementObjectSearcher), как уже было показано на некоторых других ответах. Кроме того, я не знаю, почему вы думаете, что пакеты nuget или пакеты обновления потребуются при использовании встроенной поддержки WMI .NET вместо wmic.exe ...
Ответы:
Есть несколько разных частей информации, касающихся процессоров, которые вы можете получить:
Все они могут быть разными; в случае машины с двумя двухъядерными процессорами с поддержкой гиперпоточности есть 2 физических процессора, 4 ядра и 8 логических процессоров.
Число логических процессоров доступно через класс Environment , но другая информация доступна только через WMI (и вам может потребоваться установить некоторые исправления или пакеты обновления, чтобы получить его на некоторых системах):
Не забудьте добавить ссылку в вашем проекте в System.Management.dll. В .NET Core это доступно (только для Windows) в виде пакета NuGet.
Физические процессоры:
Ядра:
Логические процессоры:
ИЛИ
Процессоры исключены из Windows:
Вы также можете использовать вызовы API Windows в файле setupapi.dll, чтобы обнаружить процессоры, которые были исключены из Windows (например, через настройки загрузки) и которые невозможно обнаружить с помощью вышеуказанных средств. Приведенный ниже код дает общее количество существующих логических процессоров (я не смог выяснить, как отличить физические процессоры от логических), включая те, которые были исключены из Windows:
источник
deviceCount
как основано на нуле, число ядер должно бытьConsole.WriteLine("Number of cores: {0}", deviceCount + 1);
[Документация]
источник
Environment.ProcessorCount
дает 32.Запросы WMI медленные, поэтому старайтесь выбирать только нужные элементы вместо использования Select *.
Следующий запрос занимает 3,4 с:
В то время как этот занимает 0,122 с:
источник
Environment.ProcessorCount должен указать количество ядер на локальном компьютере.
источник
Довольно интересно посмотреть, как .NET получает это внутренне, мягко говоря ... Это так "просто", как показано ниже:
источник
Самый простой способ =
Environment.ProcessorCount
исключить из свойства Environment.ProcessorCount
источник
Из источника .NET Framework
Вы также можете получить его с помощью PInvoke на
Kernel32.dll
Следующий код более или менее
SystemInfo.cs
взят из источника System.Web, расположенного здесь :источник
Одним из вариантов будет считывание данных из реестра. Статья MSDN по теме: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx )
Я думаю, что процессоры можно найти здесь: HKEY_LOCAL_MACHINE \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor
Я вполне уверен, что запись реестра будет там на большинстве систем.
Хотя я бы добавил свои 0,02 доллара.
источник
Следующая программа печатает логическое и физическое ядро машины Windows.
источник
Я искал то же самое, но я не хочу устанавливать какой-либо nuget или пакет обновления, поэтому я нашел это решение, оно довольно простое и прямолинейное, используя это обсуждение, я подумал, что было бы так легко выполнить эту команду WMIC и получить это значение, вот код C #. Вам нужно только использовать пространство имен System.Management (и пару стандартных пространств имен для процесса и т. Д.).
источник