Trova a livello di codice il numero di core su una macchina

C’è un modo per determinare quanti core ha una macchina da C / C ++ in modo indipendente dalla piattaforma? Se nessuna cosa del genere esiste, che ne pensi di determinarlo per piattaforma (Windows / * nix / Mac)?

C ++ 11

//may return 0 when not able to detect unsigned concurentThreadsSupported = std::thread::hardware_concurrency(); 

Riferimento: std :: thread :: hardware_concurrency


In C ++ prima di C ++ 11, non c’è un modo portabile. Invece, dovrai utilizzare uno o più dei seguenti metodi (protetti da linee #ifdef appropriate):

  • Win32

     SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); int numCPU = sysinfo.dwNumberOfProcessors; 
  • Linux, Solaris, AIX e Mac OS X> = 10.4 (cioè Tiger in poi)

     int numCPU = sysconf(_SC_NPROCESSORS_ONLN); 
  • FreeBSD, MacOS X, NetBSD, OpenBSD, ecc.

     int mib[4]; int numCPU; std::size_t len = sizeof(numCPU); /* set the mib for hw.ncpu */ mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; /* get the number of CPUs from the system */ sysctl(mib, 2, &numCPU, &len, NULL, 0); if (numCPU < 1) { mib[1] = HW_NCPU; sysctl(mib, 2, &numCPU, &len, NULL, 0); if (numCPU < 1) numCPU = 1; } 
  • HPUX

     int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL); 
  • IRIX

     int numCPU = sysconf(_SC_NPROC_ONLN); 
  • Objective-C (Mac OS X> = 10.5 o iOS)

     NSUInteger a = [[NSProcessInfo processInfo] processorCount]; NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount]; 

Questa funzionalità è parte dello standard C ++ 11.

 #include  unsigned int nthreads = std::thread::hardware_concurrency(); 

Per i compilatori più vecchi, puoi utilizzare la libreria Boost.Thread .

 #include  unsigned int nthreads = boost::thread::hardware_concurrency(); 

In entrambi i casi, hardware_concurrency() restituisce il numero di thread che l’hardware è in grado di eseguire contemporaneamente in base al numero di core CPU e unità hyper-threading.

OpenMP è supportato su molte piattaforms (incluso Visual Studio 2005) e offre a

 int omp_get_num_procs(); 

funzione che restituisce il numero di processori / core disponibili al momento della chiamata.

Se si dispone dell’accesso in linguaggio assembly, è ansible utilizzare l’istruzione CPUID per ottenere tutti i tipi di informazioni sulla CPU. È portatile tra i sistemi operativi, sebbene sia necessario utilizzare informazioni specifiche del produttore per determinare come trovare il numero di core. Ecco un documento che descrive come farlo sui chip Intel , e la pagina 11 di questo descrive le specifiche AMD.

(Quasi) funzione indipendente dalla piattaforma in c-code

 #ifdef _WIN32 #include  #elif MACOS #include  #include  #else #include  #endif int getNumCores() { #ifdef WIN32 SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; #elif MACOS int nm[2]; size_t len = 4; uint32_t count; nm[0] = CTL_HW; nm[1] = HW_AVAILCPU; sysctl(nm, 2, &count, &len, NULL, 0); if(count < 1) { nm[1] = HW_NCPU; sysctl(nm, 2, &count, &len, NULL, 0); if(count < 1) { count = 1; } } return count; #else return sysconf(_SC_NPROCESSORS_ONLN); #endif } 

Su Linux, puoi leggere il file / proc / cpuinfo e contare i core.

Notare che “numero di core” potrebbe non essere un numero particolarmente utile, potrebbe essere necessario qualificarlo un po ‘di più. Come si desidera contare CPU multi-thread come Intel HT, IBM Power5 e Power6 e, in particolare, Sun Niagara / UltraSparc T1 e T2? O ancora più interessante, MIPS 1004k con i suoi due livelli di threading hardware (supervisor AND user-level) … Per non parlare di cosa succede quando ci si sposta in sistemi supportati da hypervisor dove l’hardware potrebbe avere decine di CPU ma il proprio SO ne vede solo alcuni.

Il meglio che puoi sperare è di dire il numero di unità di elaborazione logica che hai nella tua partizione del sistema operativo locale. Dimentica di vedere la vera macchina se non sei un hypervisor. L’unica eccezione a questa regola oggi è in x86 land, ma la fine delle macchine non virtuali sta arrivando velocemente …

Ancora una ricetta per Windows: usa la variabile d’ambiente a livello di sistema NUMBER_OF_PROCESSORS :

 printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS"))); 

Probabilmente non sarai in grado di ottenerlo in modo indipendente dalla piattaforma. Windows ottieni il numero di processori.

Informazioni sul sistema Win32

Altro su OS X: sysconf(_SC_NPROCESSORS_ONLN) è disponibile solo versioni> = 10.5, non 10.4.

Un’alternativa è il codice BSD HW_AVAILCPU/sysctl() disponibile nelle versioni> = 10.2.

Windows Server 2003 e versioni successive consente di sfruttare la funzione GetLogicalProcessorInformation

http://msdn.microsoft.com/en-us/library/ms683194.aspx

Non correlato al C ++, ma su Linux di solito faccio:

 grep processor /proc/cpuinfo | wc -l 

Pratico per linguaggi di scripting come bash / perl / python / ruby.

hwloc (http://www.open-mpi.org/projects/hwloc/) vale la pena guardare. Sebbene richieda un’altra integrazione di libreria nel codice ma può fornire tutte le informazioni sul processore (numero di core, topologia, ecc.)

Su Linux, potrebbe non essere sicuro usare _SC_NPROCESSORS_ONLN perché non fa parte dello standard POSIX e il manuale sysconf lo dice tanto. Quindi esiste la possibilità che _SC_NPROCESSORS_ONLN potrebbe non essere presente:

  These values also exist, but may not be standard. [...] - _SC_NPROCESSORS_CONF The number of processors configured. - _SC_NPROCESSORS_ONLN The number of processors currently online (available). 

Un approccio semplice sarebbe quello di leggere /proc/stat o /proc/cpuinfo e contarli:

 #include #include int main(void) { char str[256]; int procCount = -1; // to offset for the first entry FILE *fp; if( (fp = fopen("/proc/stat", "r")) ) { while(fgets(str, sizeof str, fp)) if( !memcmp(str, "cpu", 3) ) procCount++; } if ( procCount == -1) { printf("Unable to get proc count. Defaulting to 2"); procCount=2; } printf("Proc Count:%d\n", procCount); return 0; } 

Utilizzando /proc/cpuinfo :

 #include #include int main(void) { char str[256]; int procCount = 0; FILE *fp; if( (fp = fopen("/proc/cpuinfo", "r")) ) { while(fgets(str, sizeof str, fp)) if( !memcmp(str, "processor", 9) ) procCount++; } if ( !procCount ) { printf("Unable to get proc count. Defaulting to 2"); procCount=2; } printf("Proc Count:%d\n", procCount); return 0; } 

Lo stesso approccio in shell usando grep:

 grep -c ^processor /proc/cpuinfo 

O

 grep -c ^cpu /proc/stat # subtract 1 from the result 

Windows (x64 e Win32) e C ++ 11

Il numero di gruppi di processori logici che condividono un singolo core del processore. (Utilizzando GetLogicalProcessorInformationEx , vedere anche GetLogicalProcessorInformation )

 size_t NumberOfPhysicalCores() noexcept { DWORD length = 0; const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length); Assert(result_first == FALSE); Assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); std::unique_ptr< uint8_t[] > buffer(new uint8_t[length]); const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get()); const BOOL result_second = GetLogicalProcessorInformationEx(RelationProcessorCore, info, &length); Assert(result_second == TRUE); size_t nb_physical_cores = 0; size_t offset = 0; do { const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX current_info = reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get() + offset); offset += current_info->Size; ++nb_physical_cores; } while (offset < length); return nb_physical_cores; } 

Si noti che l'implementazione di NumberOfPhysicalCores è lontana da IMHO (cioè "usa GetLogicalProcessorInformation o GetLogicalProcessorInformationEx "). Invece è piuttosto sottile se si legge la documentazione (esplicitamente presente per GetLogicalProcessorInformation e implicitamente presente per GetLogicalProcessorInformationEx ) su MSDN.

Il numero di processori logici. (Utilizzo di GetSystemInfo )

 size_t NumberOfSystemCores() noexcept { SYSTEM_INFO system_info; ZeroMemory(&system_info, sizeof(system_info)); GetSystemInfo(&system_info); return static_cast< size_t >(system_info.dwNumberOfProcessors); } 

Si noti che entrambi i metodi possono essere facilmente convertiti in C / C ++ 98 / C ++ 03.

Alternativa OS X: la soluzione descritta in precedenza basata su [[NSProcessInfo processInfo] processorCount] è disponibile solo su OS X 10.5.0, secondo i documenti. Per le versioni precedenti di OS X, utilizzare la funzione Carbon MPProcessors ().

Se sei un programmatore di Cocoa, non essere spaventato dal fatto che si tratti di Carbon. Hai solo bisogno di aggiungere il framework Carbon al tuo progetto Xcode e MPProcessors () sarà disponibile.

Su Linux il miglior modo programmatico per quanto ne so è da usare

 sysconf(_SC_NPROCESSORS_CONF) 

o

 sysconf(_SC_NPROCESSORS_ONLN) 

Questi non sono standard, ma sono nella mia pagina man per Linux.

Per Win32:

Mentre GetSystemInfo () ottiene il numero di processori logici , utilizzare GetLogicalProcessorInformationEx () per ottenere il numero di processori fisici .

è ansible utilizzare WMI anche in .net, ma in questo caso si dipende dal servizio wmi in esecuzione, ecc. A volte funziona localmente, ma non riesce quando lo stesso codice viene eseguito sui server. Credo che sia un problema di namespace, relativo ai “nomi” di cui stai leggendo i valori.

In Linux, è ansible eseguire il check-out di dmesg e filtrare le linee in cui l’ACPI inizializza le CPU, ad esempio:

dmesg | grep 'ACPI: Processor dmesg | grep 'ACPI: Processor

Un’altra possibilità è usare dmidecode per filtrare le informazioni sul processore.