Programowo Znajdź liczbę rdzeni na maszynie

Czy istnieje sposób, aby określić, ile rdzeni ma maszyna z C / C++ w sposób niezależny od platformy? Jeśli coś takiego nie istnieje, co z określeniem go na platformę (Windows / * nix / Mac)?

 408
c
Author: Tshepang, 2008-09-29

20 answers

C++11

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

Reference: std:: thread:: hardware_concurrency


W C++ przed C++11, nie ma przenośnego sposobu. Zamiast tego musisz użyć jednej lub więcej z następujących metod (strzeżonych przez odpowiednie linie #ifdef):

  • Win32

    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    int numCPU = sysinfo.dwNumberOfProcessors;
    
  • W 2011 roku firma została założona przez firmę Microsoft.]}
    int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
    
  • FreeBSD, MacOS X, NetBSD, OpenBSD, itd.

    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 lub iOS)

    NSUInteger a = [[NSProcessInfo processInfo] processorCount];
    NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
    
 638
Author: paxos1977,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-27 20:57:26

Ta funkcjonalność jest częścią standardu C++11.

#include <thread>

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

Dla starszych kompilatorów, możesz użyć Boost.Wątek biblioteka.

#include <boost/thread.hpp>

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

W obu przypadkach, hardware_concurrency() Zwraca liczbę wątków, które sprzęt jest w stanie wykonać jednocześnie na podstawie liczby rdzeni procesora i jednostek hyper-threadingu.

 188
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-11 17:59:32

OpenMP jest obsługiwany na wielu platformach (w tym Visual Studio 2005) i oferuje

int omp_get_num_procs();

Funkcja, która zwraca liczbę procesorów/rdzeni dostępnych w momencie wywołania.

 55
Author: macbirdie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 11:55:20

Jeśli masz dostęp do języka asemblera, możesz użyć instrukcji CPUID, aby uzyskać wszelkiego rodzaju informacje o procesorze. Jest przenośny między systemami operacyjnymi, ale musisz użyć informacji specyficznych dla producenta, aby określić, jak znaleźć liczbę rdzeni. Oto dokument, który opisuje, jak to zrobić na chipach Intela, a strona 11 z Ta opisuje specyfikację AMD.

 37
Author: Head Geek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 19:28:44

(prawie) funkcja niezależna od platformy w kodzie c

#ifdef _WIN32
#include <windows.h>
#elif MACOS
#include <sys/param.h>
#include <sys/sysctl.h>
#else
#include <unistd.h>
#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
}
 31
Author: Dirk-Jan Kroon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 13:48:51

W Linuksie można odczytać plik / proc / cpuinfo i policzyć rdzenie.

 15
Author: JesperE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 19:55:25

Zauważ, że "liczba rdzeni" może nie być szczególnie przydatną liczbą, być może będziesz musiał ją nieco bardziej zakwalifikować. Jak liczyć wielowątkowe procesory takie jak Intel HT, IBM Power5 i Power6, a najbardziej znane to Niagara/UltraSparc T1 i T2? A co ciekawsze, MIPS 1004k z dwoma poziomami gwintowania sprzętowego (na poziomie nadzorcy i użytkownika)... Nie wspominając o tym, co się dzieje, gdy przenosisz się do systemów obsługiwanych przez hipernadzorcę, gdzie sprzęt może mieć dziesiątki procesorów, ale Twój system operacyjny widzi tylko kilka.

Najlepsze, na co możesz liczyć, to podanie liczby logicznych jednostek przetwarzania, które masz w lokalnej partycji systemu operacyjnego. Zapomnij o oglądaniu prawdziwej maszyny, chyba że jesteś hipernadzorcą. Jedynym wyjątkiem od tej reguły jest dziś Ziemia x86, ale koniec maszyn nie wirtualnych nadchodzi szybko...

 10
Author: jakobengblom2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 19:21:37

Jeszcze jeden przepis na Windows: użyj systemowej zmiennej środowiskowej NUMBER_OF_PROCESSORS:

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
 7
Author: Constantin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-13 15:09:15

Prawdopodobnie nie będziesz w stanie uzyskać go w sposób niezależny od platformy. Windows dostajesz liczbę procesorów.

Informacje O Systemie Win32

 7
Author: Ken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 19:18:48

Więcej O OS X: sysconf(_SC_NPROCESSORS_ONLN) jest dostępna tylko Wersja >= 10.5, a nie 10.4.

Alternatywą jest HW_AVAILCPU/sysctl() kod BSD, który jest dostępny w wersjach > = 10.2.

 5
Author: sezero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-02 20:15:27

Windows Server 2003 i nowszy pozwala na wykorzystanie funkcji GetLogicalProcessorInformation

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

 4
Author: Chris Ballance,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 19:54:54

Niezwiązany z C++, ale na Linuksie zwykle robię:

grep processor /proc/cpuinfo | wc -l

Przydatne dla języków skryptowych, takich jak bash / perl / python / ruby.

 4
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 19:31:05

Windows (x64 i Win32) oraz C++11

Liczba grup procesorów logicznych współdzielących jeden rdzeń PROCESORA. (używając GetLogicalProcessorInformationEx , zobacz 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;
}

zauważ, że implementacja {[2] } jest IMHO daleka od trywialnej (np."użyj GetLogicalProcessorInformation lub GetLogicalProcessorInformationEx"). Zamiast tego jest to raczej subtelne, jeśli czyta się dokumentację (jawnie obecną dla GetLogicalProcessorInformation i niejawnie obecną dla GetLogicalProcessorInformationEx) w MSDN.

Liczba procesorów logicznych. (Using 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);
}

zauważ, że obie metody można łatwo przekonwertować do C / C++98/C++03.

 4
Author: Matthias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 16:58:23

Hwloc (http://www.open-mpi.org/projects/hwloc/) warto zajrzeć. Chociaż wymaga innej biblioteki integracji z kodem, ale może dostarczyć wszystkie informacje o procesorze (liczba rdzeni, topologia, itp.)

 3
Author: Akhil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 19:11:16

W Linuksie używanie _SC_NPROCESSORS_ONLN może nie być bezpieczne, ponieważ nie jest częścią standardu POSIX, a instrukcja sysconf stwierdza tak samo. Jest więc możliwość, że _SC_NPROCESSORS_ONLN może nie być obecny:

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

Proste podejście byłoby odczytać /proc/stat lub /proc/cpuinfo i policzyć je:

#include<unistd.h>
#include<stdio.h>

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

Używając /proc/cpuinfo:

#include<unistd.h>
#include<stdio.h>

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

To samo podejście w powłoce przy użyciu grep:

grep -c ^processor /proc/cpuinfo

Lub

grep -c ^cpu /proc/stat # subtract 1 from the result
 3
Author: P.P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-30 11:06:58

Alternatywa dla OS X: rozwiązanie opisane wcześniej w oparciu o [[nsprocessinfo processorcount] jest dostępne tylko w OS X 10.5.0, zgodnie z dokumentami. Dla wcześniejszych wersji OS X użyj funkcji Carbon MPProcessors ().

Jeśli jesteś programistą kakao, nie denerwuj się faktem, że jest to węgiel. Wystarczy dodać Framework węgla do projektu Xcode i MPProcessors () będą dostępne.

 2
Author: gauss256,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-12 20:00:28

Na Linuksie najlepszym sposobem programowania z tego co wiem jest użycie

sysconf(_SC_NPROCESSORS_CONF)

Lub

sysconf(_SC_NPROCESSORS_ONLN)

Nie są standardowe, ale znajdują się na mojej stronie podręcznika dla Linuksa.

 2
Author: Evan Teran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 19:19:24

Dla Win32:

Podczas gdy GetSystemInfo () pobiera liczbę logicznych Procesorów, użyj GetLogicalProcessorInformationEx () aby uzyskać liczbę fizycznych Procesorów.

 2
Author: irrlicht_ist_toll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-27 08:51:02

Możesz też używać WMI w. Net, ale wtedy zależy ci na uruchomionej usłudze WMI itd. Czasami działa lokalnie, ale potem zawodzi, gdy ten sam kod jest uruchamiany na serwerach. Uważam, że to problem z przestrzenią nazw, związany z "nazwami", których wartości czytasz.

 -2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-21 19:02:21

W Linuksie możesz sprawdzić dmesg i filtrować linie, w których ACPI inicjalizuje Procesory, coś w stylu:

dmesg | grep 'ACPI: Processor'

Inną możliwością jest użycie dmidecode do filtrowania informacji o procesorze.

 -3
Author: Hernán,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 07:48:57