Programming/C

C언어에서 시스템의 물리적 CPU 코어 수 확인하기

moxie2ks 2025. 4. 15. 18:01
728x90
반응형

개요

컴퓨터 시스템에서 물리적 CPU 코어 수를 정확히 파악하는 것은 소프트웨어 개발, 시스템 최적화, 성능 벤치마킹에 중요한 요소이다. 이 글에서는 Windows와 Linux/POSIX 시스템에서 물리적 CPU 코어 수를 확인하는 C 코드 구현 방법을 상세히 분석한다.

설명

물리적 CPU 코어 수는 컴퓨팅 작업의 병렬 처리 능력을 결정하는 주요 요소로, 소프트웨어 개발자가 멀티스레딩 구현과 리소스 할당을 최적화할 때 필수적인 정보이다. 하이퍼스레딩 기술로 인해 논리적 프로세서 수와 물리적 코어 수는 다를 수 있어, 정확한 물리적 코어 수 확인 방법이 필요하다. 운영체제별로 상이한 API를 통해 이 정보에 접근할 수 있으며, 크로스 플랫폼 애플리케이션 개발 시 이러한 차이를 고려해야 한다.

특징

Windows 시스템에서의 구현

Windows 시스템에서는 Windows API의 GetLogicalProcessorInformation 함수를 활용하여 물리적 CPU 코어 수를 확인한다. 이 접근법의 주요 특징은 다음과 같다:

  1. Windows.h 헤더 파일을 포함하여 필요한 API에 접근
  2. GetLogicalProcessorInformation 함수로 프로세서 정보 수집
  3. RelationProcessorCore 관계를 가진 정보만 필터링하여 물리적 코어 수 계산
  4. 비트 연산을 통해 프로세서 마스크 분석

Linux/POSIX 시스템에서의 구현

Linux 및 기타 POSIX 시스템에서는 sysconf 함수를 사용하여 간단하게 프로세서 정보를 획득한다:

  1. unistd.h 헤더 파일을 포함
  2. sysconf(_SC_NPROCESSORS_CONF) 함수 호출로 구성된 프로세서 수 확인
  3. Windows 구현에 비해 상대적으로 단순한 코드 구조

크로스 플랫폼 지원

제시된 코드는 전처리기 지시문(#if defined(_WIN32))을 사용하여 컴파일 시점에 적절한 구현을 선택함으로써 크로스 플랫폼 지원을 제공한다. 이는 단일 코드베이스로 여러 운영체제를 지원할 수 있게 한다.

예제

아래 코드는 Windows와 Linux/POSIX 시스템에서 물리적 CPU 코어 수를 확인하는 완전한 구현 예시이다:

#include 
#if defined(_WIN32)
    #include 
#else
    #include 
#endif

#if defined(_WIN32)
static int getPhysicalCpuCores()
{
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
    DWORD bufferSize = 0;
    DWORD byteOffset = 0;
    DWORD logicalProcessorCount = 0;
    DWORD physicalProcessorCount = 0;

    // 필요한 버퍼 크기 얻기
    GetLogicalProcessorInformation(NULL, &bufferSize);

    buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(bufferSize);
    if (buffer == NULL)
    {
        perror("Memory allocation error");
        return -1;
    }

    // 프로세서 정보 얻기
    if (!GetLogicalProcessorInformation(buffer, &bufferSize))
    {
        perror("GetLogicalProcessorInformation error");
        free(buffer);
        return -1;
    }

    while (byteOffset < bufferSize)
    {
        if (buffer[byteOffset / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)].Relationship == RelationProcessorCore)
        {
            logicalProcessorCount += CountSetBits(buffer[byteOffset / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)].ProcessorMask);
            physicalProcessorCount++;
        }
        byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    }

    free(buffer);

    return physicalProcessorCount;
}

static DWORD CountSetBits(ULONG_PTR bitMask) {
    DWORD LSHIFT = sizeof(ULONG_PTR) * 8 - 1;
    DWORD bitSetCount = 0;
    ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
    DWORD i;

    for (i = 0; i <= LSHIFT; ++i) {
        bitSetCount += ((bitMask & bitTest) ? 1 : 0);
        bitTest /= 2;
    }

    return bitSetCount;
}
#endif

int get_number_of_cpu_core(void)
{
    int number_of_cpu_core = 0;

#if defined(_WIN32)
    number_of_cpu_core = getPhysicalCpuCores();
#else
    /*
        Specified <https://man7.org/linux/man-pages/man3/sysconf.3.html>

        - _SC_NPROCESSORS_CONF
            The number of processors configured.  See also
            get_nprocs_conf(3).
    */
    number_of_cpu_core = (int)sysconf(_SC_NPROCESSORS_CONF);
#endif

    return number_of_cpu_core;
}

int main(void)
{
    printf("Number of CPU core : %d", get_number_of_cpu_core());
    return 0;
}

Windows 구현 상세 분석

Windows 시스템에서의 물리적 CPU 코어 수 계산 과정은 다음과 같다:

  1. GetLogicalProcessorInformation 함수를 먼저 NULL 포인터로 호출하여 필요한 버퍼 크기를 확인한다.
  2. 필요한 크기만큼 메모리를 할당한다.
  3. 할당된 버퍼로 다시 GetLogicalProcessorInformation 함수를 호출하여 프로세서 정보를 가져온다.
  4. 버퍼를 순회하며 Relationship 멤버가 RelationProcessorCore인 항목을 찾아 물리적 코어 수를 계산한다.
  5. ProcessorMask에 설정된 비트 수를 통해 논리적 프로세서 수도 계산할 수 있다.
  6. 메모리를 해제하고 물리적 코어 수를 반환한다.

Linux/POSIX 구현 상세 분석

Linux 및 POSIX 시스템에서는 sysconf 함수를 사용하여 간단하게 구성된 프로세서 수를 얻는다:

  1. _SC_NPROCESSORS_CONF 상수를 인자로 sysconf 함수를 호출한다.
  2. 반환된 값을 정수형으로 변환하여 사용한다.

실행 결과는 간단하게 물리적 CPU 코어 수를 출력한다:

Number of CPU core : 4

결론

물리적 CPU 코어 수 확인은 운영체제에 따라 상이한 방법을 요구하지만, 전처리기 지시문을 활용하여 크로스 플랫폼 코드로 구현할 수 있다. Windows 시스템에서는 보다 복잡한 API 호출과 처리 과정이 필요한 반면, Linux/POSIX 시스템에서는 상대적으로 간단한 함수 호출로 정보를 얻을 수 있다. 이러한 시스템 정보 확인 방법은 성능 최적화, 리소스 관리, 병렬 처리 구현 등 다양한 소프트웨어 개발 상황에서 활용될 수 있다.

참고문헌

  1. Windows API - GetLogicalProcessorInformation: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
  2. Linux Man Pages - sysconf: https://man7.org/linux/man-pages/man3/sysconf.3.html
  3. Understanding CPU Core Counts: https://www.intel.com/content/www/us/en/developer/articles/guide/processor-specific-performance-analysis-papers.html
728x90
반응형