Apakah Anda perlu tahu berapa banyak core yang ada atau berapa banyak prosesor logis yang ada? Untuk hanya menjalankan beberapa utas, mungkin keduanya cukup, tetapi ada skenario di mana perbedaannya mungkin penting.
Kevin Kibler
Apakah ada cara yang lebih baru untuk melakukan ini?
MoonKnight
Jawaban:
477
Ada beberapa informasi berbeda yang berkaitan dengan prosesor yang bisa Anda dapatkan:
Jumlah prosesor fisik
Jumlah inti
Jumlah prosesor logis.
Ini semua bisa berbeda; dalam kasus mesin dengan 2 prosesor dual-core hyper-threading-enabled, ada 2 prosesor fisik, 4 core, dan 8 prosesor logis.
Jumlah prosesor logis tersedia melalui kelas Lingkungan , tetapi informasi lainnya hanya tersedia melalui WMI (dan Anda mungkin harus menginstal beberapa perbaikan terbaru atau paket layanan untuk mendapatkannya di beberapa sistem):
Pastikan untuk menambahkan referensi dalam proyek Anda ke System.Management.dll
Di .NET Core, ini tersedia (hanya untuk Windows) sebagai paket NuGet.
Prosesor Fisik:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()){Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);}
Core:
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);
Prosesor logis:
Console.WriteLine("Number Of Logical Processors: {0}",Environment.ProcessorCount);
ATAU
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()){Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);}
Prosesor yang dikecualikan dari Windows:
Anda juga dapat menggunakan panggilan Windows API di setupapi.dll untuk menemukan prosesor yang telah dikecualikan dari Windows (misalnya melalui pengaturan boot) dan tidak terdeteksi menggunakan cara di atas. Kode di bawah ini memberikan jumlah total prosesor logis (saya belum dapat menemukan cara membedakan fisik dari prosesor logis) yang ada, termasuk yang telah dikecualikan dari 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: Benar, tapi saya berharap itu dalam format yang lebih bagus. Keterjangkauan cukup rendah ketika Anda harus membangun kueri string mentah.
Kevin Kibler
5
Pembuat Kode WMI akan membantu dengan penemuan nilai dan pembuatan kueri (bahkan dapat menghasilkan stubs di c # / vb.net).
StingyJack
4
Ada di System.Management.dll. Apakah Anda memasukkan referensi ke majelis itu dalam proyek Anda?
Kevin Kibler
2
Masalah kecil satu per satu dalam kode di atas. Karena deviceCountberbasis nol, jumlah inti harus berupa output seperti ini:Console.WriteLine("Number of cores: {0}", deviceCount + 1);
Francis Litterio
2
Tidakkah Anda menyebabkan masalah dengan tidak membuang objek dan pencari manajemen?
Sederhana sekali, sampai-sampai aku menangis. Terima kasih atas jawabannya!
MrGreggles
70
Ini memberikan jumlah prosesor logis, bukan jumlah core.
Kevin Kibler
8
@KevinKibler Dari pertanyaan, saya curiga OP tidak mengerti perbedaannya, dan jika Anda tidak tahu perbedaannya, ini mungkin yang Anda inginkan.
Glenn Maynard
1
Ini juga mengembalikan hitungan salah pada banyak sistem inti. Saya menjalankan dua prosesor inti dodeca dengan hyper-threading, yang memberi saya total 48 prosesor logis. Environment.ProcessorCountmenghasilkan 32.
Allen Clark Copeland Jr
1
@AlexanderMorou, ya ini akan gagal memberikan hasil yang akurat pada beberapa server multi-CPU. Ada perbaikan untuk ini, tetapi belum mengujinya.
TheLegendaryCopyCoder
35
Kueri WMI lambat, jadi cobalah Pilih hanya anggota yang diinginkan daripada menggunakan Pilih *.
Permintaan berikut membutuhkan waktu 3.4s:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
Sementara yang ini membutuhkan 0,122:
foreach(var item innewSystem.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())
Anda menjalankan sistem apa ini? Saya menggunakan beberapa "Pilih *" query dan tidak mengambil di mana saja dekat 3,4 detik, diuji pada ribuan komputer yang perangkat lunak saya ditempatkan di. Saya melakukan Select * karena saya mendapatkan beberapa properti dari objek. Namun, saya melakukannya sedikit berbeda: membuat ObjectQuery pada Select *; dapatkan ManagementObjectCollection; kemudian foreach ManagementObject di ManagementObjectCollection.
deegee
@deegee: Anda benar, permintaan itu sendiri tidak memakan waktu lebih lama dengan "Pilih *", hanya saja penguraian int di bawah ini lambat jika iterasi semua nilai yang dikembalikan bukan hanya NumberOfCores.
using System;classSample{publicstaticvoidMain(){Console.WriteLine("The number of processors "+"on this computer is {0}.",Environment.ProcessorCount);}}
Ini akan memberikan sejumlah prosesor yang sudah tersedia di Environment.ProcessorCount, apakah ada cara serupa lainnya untuk mendapatkan jumlah core untuk setiap prosesor?
Armen
0
Program berikut mencetak inti logis dan fisik mesin 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
*/
Pertanyaan ini ditandai .NET; kode Anda bukan .NET code.
Wai Ha Lee
-1
Saya mencari hal yang sama tetapi saya tidak ingin menginstal paket nuget atau servicepack, jadi saya menemukan solusi ini, sangat sederhana dan lurus ke depan, menggunakan diskusi ini , saya pikir akan sangat mudah untuk menjalankan perintah WMIC itu dan dapatkan nilai itu, berikut adalah kode C #. Anda hanya perlu menggunakan namespace System.Management (dan pasangan ruang nama standar lebih untuk proses dan sebagainya).
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();
Tidak yakin mengapa Anda membuat kueri WMI sederhana sangat rumit. Memulai baris perintah WMI sebagai proses eksternal dan mem-parsing outputnya benar-benar tidak perlu. .NET memiliki dukungan bawaan untuk kueri WMI (System.Management.ManagementObjectSearcher), karena beberapa jawaban lain di sini sudah diilustrasikan. Juga, saya tidak tahu mengapa Anda berpikir paket nuget atau paket layanan akan diperlukan saat menggunakan dukungan WMI built-in .NET bukannya wmic.exe ...
Jawaban:
Ada beberapa informasi berbeda yang berkaitan dengan prosesor yang bisa Anda dapatkan:
Ini semua bisa berbeda; dalam kasus mesin dengan 2 prosesor dual-core hyper-threading-enabled, ada 2 prosesor fisik, 4 core, dan 8 prosesor logis.
Jumlah prosesor logis tersedia melalui kelas Lingkungan , tetapi informasi lainnya hanya tersedia melalui WMI (dan Anda mungkin harus menginstal beberapa perbaikan terbaru atau paket layanan untuk mendapatkannya di beberapa sistem):
Pastikan untuk menambahkan referensi dalam proyek Anda ke System.Management.dll Di .NET Core, ini tersedia (hanya untuk Windows) sebagai paket NuGet.
Prosesor Fisik:
Core:
Prosesor logis:
ATAU
Prosesor yang dikecualikan dari Windows:
Anda juga dapat menggunakan panggilan Windows API di setupapi.dll untuk menemukan prosesor yang telah dikecualikan dari Windows (misalnya melalui pengaturan boot) dan tidak terdeteksi menggunakan cara di atas. Kode di bawah ini memberikan jumlah total prosesor logis (saya belum dapat menemukan cara membedakan fisik dari prosesor logis) yang ada, termasuk yang telah dikecualikan dari Windows:
sumber
deviceCount
berbasis nol, jumlah inti harus berupa output seperti ini:Console.WriteLine("Number of cores: {0}", deviceCount + 1);
[Dokumentasi]
sumber
Environment.ProcessorCount
menghasilkan 32.Kueri WMI lambat, jadi cobalah Pilih hanya anggota yang diinginkan daripada menggunakan Pilih *.
Permintaan berikut membutuhkan waktu 3.4s:
Sementara yang ini membutuhkan 0,122:
sumber
Environment.ProcessorCount harus memberi Anda jumlah core pada mesin lokal.
sumber
Ini agak menarik untuk melihat bagaimana. NET mendapatkan ini secara internal untuk sedikitnya ... Ini "sesederhana" seperti di bawah ini:
sumber
Cara termudah =
Environment.ProcessorCount
Contoh dari Environment.ProcessorCount Property
sumber
Dari sumber .NET Framework
Anda juga bisa mendapatkannya dengan PInvoke aktif
Kernel32.dll
Kode berikut ini kurang lebih berasal dari
SystemInfo.cs
dari sumber System.Web yang terletak di sini :sumber
Salah satu opsi adalah membaca data dari registri. Artikel MSDN Pada Topik: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx )
Prosesor, saya yakin dapat ditemukan di sini, HKEY_LOCAL_MACHINE \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor
Saya cukup yakin entri registri akan ada di sebagian besar sistem.
Meskipun saya akan membuang $ 0,02 saya di.
sumber
Program berikut mencetak inti logis dan fisik mesin windows.
sumber
Saya mencari hal yang sama tetapi saya tidak ingin menginstal paket nuget atau servicepack, jadi saya menemukan solusi ini, sangat sederhana dan lurus ke depan, menggunakan diskusi ini , saya pikir akan sangat mudah untuk menjalankan perintah WMIC itu dan dapatkan nilai itu, berikut adalah kode C #. Anda hanya perlu menggunakan namespace System.Management (dan pasangan ruang nama standar lebih untuk proses dan sebagainya).
sumber