development

프로그래밍 방식으로 머신에서 코어 수 찾기

big-blog 2020. 2. 17. 22:20
반응형

프로그래밍 방식으로 머신에서 코어 수 찾기


플랫폼 독립적 인 방식으로 머신이 C / C ++의 코어 수를 결정하는 방법이 있습니까? 그러한 것이 존재하지 않으면 플랫폼별로 결정하는 것은 어떻습니까 (Windows / * nix / Mac)?


C ++ 11

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

참조 : std :: thread :: hardware_concurrency


C ++ 11 이전의 C ++에서는 이식 가능한 방법이 없습니다. 대신 다음 방법 중 하나 이상을 사용해야합니다 (적절한 #ifdef행으로 보호 ).

  • Win32

    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    int numCPU = sysinfo.dwNumberOfProcessors;
    
  • Linux, Solaris, AIX 및 Mac OS X> = 10.4 (즉, Tiger 이상)

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

    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 또는 iOS)

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

이 기능은 C ++ 11 표준의 일부입니다.

#include <thread>

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

구형 컴파일러의 경우 Boost.Thread 라이브러리를 사용할 수 있습니다 .

#include <boost/thread.hpp>

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

두 경우 모두, hardware_concurrency()CPU 코어 수와 하이퍼 스레딩 장치 수를 기반으로 하드웨어가 동시에 실행할 수있는 스레드 수를 반환합니다.


OpenMP 는 많은 플랫폼 (Visual Studio 2005 포함)에서 지원되며

int omp_get_num_procs();

호출시 사용 가능한 프로세서 / 코어 수를 반환하는 함수입니다.


어셈블리 언어 액세스 권한이있는 경우 CPUID 명령어를 사용하여 CPU에 대한 모든 종류의 정보를 얻을 수 있습니다. 운영 체제간에 이식 가능하지만 제조업체 별 정보를 사용하여 코어 수를 찾는 방법을 결정해야합니다. 다음 은 Intel 칩 에서 수행하는 방법을 설명하는 문서이며이 11 페이지 는 AMD 사양을 설명합니다.


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
}

Linux에서는 / proc / cpuinfo 파일을 읽고 코어를 계산할 수 있습니다.


"코어 수"는 특히 유용한 숫자가 아닐 수 있으므로 조금 더 한정해야 할 수도 있습니다. Intel HT, IBM Power5 및 Power6과 같은 멀티 스레드 CPU와 Sun의 Niagara / UltraSparc T1 및 T2를 가장 잘 계산하려면 어떻게 하시겠습니까? 더 흥미로운 것은 두 가지 수준의 하드웨어 스레딩 (감독자 및 사용자 수준)을 갖춘 MIPS 1004k입니다. 하드웨어에 수십 개의 CPU가 있지만 특정 OS가있는 하이퍼 바이저 지원 시스템으로 이동할 때 발생하는 상황은 말할 것도 없습니다. 몇 개만 봅니다.

로컬 OS 파티션에있는 논리 처리 장치 수를 알려주는 것이 가장 좋습니다. 하이퍼 바이저가 아니라면 실제 시스템을 보는 것을 잊어 버리십시오. 오늘날이 규칙에 대한 유일한 예외는 x86 육상이지만, 비가 상 머신의 끝은 빨라지고 있습니다 ...


하나 이상의 Windows 레시피 : 시스템 전체 환경 변수 사용 NUMBER_OF_PROCESSORS:

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

당신은 아마 플랫폼 독립적 인 방법으로 그것을 얻을 수 없을 것입니다. Windows에는 많은 프로세서가 있습니다.

Win32 시스템 정보


Windows (x64 및 Win32) 및 C ++ 11

단일 프로세서 코어를 공유하는 논리 프로세서 그룹 수입니다. (사용 GetLogicalProcessorInformationEx를 참조 GetLogicalProcessorInformation을 뿐만 아니라)

size_t NumberOfPhysicalCores() noexcept {

    DWORD length = 0;
    const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
    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 != FALSE);

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

구현은 NumberOfPhysicalCores사소한 것과는 거리가 멀다 (즉, "사용 GetLogicalProcessorInformation또는 GetLogicalProcessorInformationEx"). 대신 MSDN 의 설명서 (명시 적으로 존재 GetLogicalProcessorInformation하고 암시 적으로 존재 함)를 읽는다면 다소 미묘합니다 GetLogicalProcessorInformationEx.

논리 프로세서 수 ( 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);
}

두 방법 모두 C / C ++ 98 / C ++ 03으로 쉽게 변환 될 수 있습니다.


OS X에 대한 추가 정보 : sysconf(_SC_NPROCESSORS_ONLN)10.4가 아닌> = 10.5 버전에서만 사용 가능합니다.

대안은 HW_AVAILCPU/sysctl()BSD 코드이며> = 10.2 버전에서 사용할 수 있습니다.


Windows Server 2003 이상에서는 GetLogicalProcessorInformation 함수를 활용할 수 있습니다

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


C ++과 관련이 없지만 Linux에서는 보통 다음을 수행합니다.

grep processor /proc/cpuinfo | wc -l

bash / perl / python / ruby와 같은 스크립팅 언어에 편리합니다.


hwloc (http://www.open-mpi.org/projects/hwloc/)을 살펴볼 가치가 있습니다. 코드에 다른 라이브러리 통합이 필요하지만 프로세서에 대한 모든 정보 (코어 수, 토폴로지 등)를 제공 할 수 있습니다.


Linux에서는 _SC_NPROCESSORS_ONLNPOSIX 표준 및 sysconf 매뉴얼 상태에 포함 되지 않으므로 사용하기에 안전하지 않을 수 있습니다 . 따라서 존재 _SC_NPROCESSORS_ONLN하지 않을 가능성이 있습니다.

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

간단한 접근법은 그것들 을 읽 /proc/stat거나 /proc/cpuinfo세는 것입니다.

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

사용 /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;
}

grep을 사용하는 쉘에서 동일한 접근법 :

grep -c ^processor /proc/cpuinfo

또는

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

OS X 대안 : [[NSProcessInfo processInfo] processorCount]를 기반으로 앞에서 설명한 솔루션은 문서에 따라 OS X 10.5.0에서만 사용할 수 있습니다. 이전 버전의 OS X의 경우 Carbon 함수 MPProcessors ()를 사용하십시오.

코코아 프로그래머라면 이것이 카본이라는 사실에 놀라지 마십시오. Xcode 프로젝트에 Carbon 프레임 워크를 추가하기 만하면 MPProcessors ()를 사용할 수 있습니다.


리눅스에서는 내가 아는 한 프로그래밍 방식이 가장 좋습니다.

sysconf(_SC_NPROCESSORS_CONF)

또는

sysconf(_SC_NPROCESSORS_ONLN)

이것들은 표준은 아니지만 Linux의 맨 페이지에 있습니다.


Win32의 경우 :

GetSystemInfo ()는 논리 프로세서 수를 가져 오는 반면 GetLogicalProcessorInformationEx ()사용 하여 실제 프로세서 수를 가져옵니다 .


.net에서도 WMI를 사용할 수 있지만 wmi 서비스 실행 등에 의존합니다. 때로는 로컬에서 작동하지만 서버에서 동일한 코드가 실행될 때 실패합니다. 나는 그것이 읽고있는 "이름"과 관련된 네임 스페이스 문제라고 생각합니다.


Linux에서는 dmesg를 체크 아웃하고 ACPI가 CPU를 초기화하는 라인을 필터링 할 수 있습니다.

dmesg | grep 'ACPI: Processor'

다른 가능성은 dmidecode를 사용하여 프로세서 정보를 필터링하는 것입니다.

참고 URL : https://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine



도와주세요.
반응형