VMware, KVM, Hyper-V 등 다양한 하이퍼바이저에서 가상 머신을 생성하다 보면, 할당된 모든 가상 프로세서 소켓(vCPU)을 게스트 OS가 인식하지 못하는 경우가 종종 발생합니다. 실제 사례를 보면, KVM 가상 머신에 8개의 vCPU를 할당하고 Windows 10을 게스트 OS로 설치했을 때, Windows는 이 vCPU들을 별도의 프로세서(코어가 아님)로 인식하여 2개만 사용할 수 있었습니다.
Windows 10 가상 머신이 2코어만 사용하는 문제
Windows 장치 관리자를 열어보면 할당된 모든 코어가 QEMU Virtual CPU version 2.5+라는 이름의 8개 개별 가상 프로세서로 표시되는 것을 확인할 수 있습니다.

그러나 Windows 10의 시스템 속성(컴퓨터 → 속성)과 작업 관리자에서는 2개의 QEMU 가상 프로세서만 사용 가능한 것으로 나타납니다.

즉, Windows 10은 코어를 아무리 추가해도 2개만 사용할 수 있습니다. 반면 같은 하이퍼바이저에서 Windows Server 2016을 실행하는 가상 서버는 할당된 16개 vCPU를 모두 정상적으로 인식합니다.
Windows 버전별 지원 프로세서 수
문제의 원인은 데스크톱용 Windows 버전(Windows 10/8.1/7)이 컴퓨터에서 사용할 수 있는 최대 물리적 프로세서(소켓) 수에 제한을 두고 있다는 점입니다.
- Windows 10 Home – 1 CPU
- Windows 10 Professional – 2 CPU
- Windows 10 Workstation – 최대 4 CPU
- Windows Server 2016 – 최대 64 CPU
다행히 이 제한은 코어 수와는 무관합니다. 따라서 가상 머신의 성능을 높이려면 더 많은 코어를 가진 프로세서 구성을 사용하면 됩니다. 대부분의 하이퍼바이저는 vCPU를 프로세서, 프로세서 코어, 심지어 스레드 형태로도 제공할 수 있습니다. 예를 들어 8개의 vCPU 대신 소켓당 4코어씩 2개의 vCPU(2소켓)를 구성할 수 있습니다. 이제 주요 하이퍼바이저별로 가상 프로세서를 코어 형태로 할당하는 방법과, 현대 프로세서에 적용된 NUMA 아키텍처와의 연관성을 살펴보겠습니다.
KVM에서 가상 코어 및 vCPU 관리하기
Windows 10이 실행 중인 KVM 가상 머신에서는 할당된 모든 가상 코어가 별도의 프로세서로 인식됩니다.
가상 머신에 할당된 모든 CPU 리소스를 활용하려면, 8개의 vCPU 대신 '8코어 1개 프로세서', '코어 4개씩 2개 vCPU', 또는 '스레드 2개로 구성된 4코어 1개 vCPU'로 인식되도록 변경해야 합니다. KVM 가상 머신의 가상 코어 할당 방식을 변경해 보겠습니다.
먼저 가상 머신을 종료합니다:
# virsh shutdown w10testvm — 여기서 w10testvm은 가상 머신의 이름입니다.
참고로 virsh 명령어를 사용하면 콘솔에서 KVM 가상 머신을 다양하게 관리할 수 있습니다.
KVM 가상 머신의 현재 XML 설정을 확인합니다:
# virsh dumpxml w10testvm
VM의 CPU 설정을 나타내는 블록은 다음과 같습니다:
<vcpu placement='static'>8</vcpu>
<cputune>
<shares>1000</shares>
</cputune>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-i440fx-rhel7.6.0'>hvm</type>
<bootmenu enable='yes'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
현재 8개의 vCPU가 설정되어 있는 것을 확인할 수 있습니다. 이제 설정을 변경해 보겠습니다:
# virsh edit w10testvm
</features> 태그 바로 뒤에 다음 블록을 추가합니다:
<cpu mode='host-passthrough' check='none'>
<topology sockets='1' cores='4' threads='2'/>
</cpu>
각 옵션의 의미는 다음과 같습니다:
host-passthrough: 클러스터 노드의 물리적 프로세서를 가상 머신이 그대로 인식하는 에뮬레이션 모드입니다.sockets='1': vCPU(소켓)가 1개임을 의미합니다.cores='4': 소켓당 코어가 4개임을 의미합니다.threads='2': 코어당 스레드가 2개임을 의미합니다.
설정 파일을 저장하고 가상 머신을 시작합니다. Windows 10 게스트 VM에 로그인한 후 작업 관리자나 리소스 모니터를 실행하여, Windows가 할당된 모든 가상 코어를 인식하는지 확인합니다.

설정 변경 후 시스템 속성에는 가상 프로세서 대신 호스트의 실제 물리적 프로세서인 Intel(R) Xeon(R) Silver 4114 CPU가 표시됩니다.

이렇게 하여 기존 2코어로는 애플리케이션이 원활하게 작동하지 못하던 부하 문제를 해결할 수 있었습니다.
VMware VM의 vCPU당 코어 수 설정
VMware 가상 머신의 vCPU 표시 방식은 vSphere Client 인터페이스에서 손쉽게 변경할 수 있습니다.
- VM을 종료하고 설정 창을 엽니다.
- CPU 섹션을 확장합니다.
- 게스트 OS가 코어 4개씩 2개의 프로세서로 인식하도록 VM 구성을 변경합니다. Cores per Socket 값을 4로 설정하면, 게스트 OS는 소켓당 4코어씩 2개의 CPU(2소켓 × 4코어)로 인식합니다.

- 변경 사항을 저장하고 VM을 실행합니다.
가상 머신 vCPU와 NUMA 아키텍처
vCPU와 코어를 가상 머신에 할당할 때 반드시 이해해야 할 추가적인 사항들이 있습니다.
소켓당 코어 수를 지정하기 전에 시스템이 NUMA 아키텍처(대부분의 최신 CPU에서 사용)를 지원하는지 확인해야 합니다. 물리적 소켓(NUMA 노드)에서 사용 가능한 코어 수보다 많은 코어(및 전체 vCPU 수)를 하나의 VM에 할당하는 것은 권장되지 않습니다. 가상 머신이 단일 물리적 NUMA 노드에 배치되면 해당 노드가 제공하는 빠른 로컬 RAM을 활용할 수 있습니다. 반면 여러 NUMA 노드에 걸치게 되면 프로세스가 다른 NUMA 노드의 응답을 기다려야 하므로(더 긴 지연 시간), 성능 저하가 발생합니다.
VM에 두 개의 개별 가상 소켓을 할당하면 하이퍼바이저가 이를 서로 다른 NUMA 노드에서 실행할 수 있으며, 이 역시 VM 성능에 영향을 미칩니다.
필요한 vCPU 수가 1개의 물리적 소켓(NUMA 노드)의 코어 수보다 많다면, 필요한 코어 수를 갖춘 여러 개의 가상 소켓(프로세서)을 생성해야 합니다. 또한 홀수 개의 프로세서 구성은 피하는 것이 좋으며(vCPU 1개를 추가하는 편이 유리함), 이러한 원칙을 지키면 가상 머신의 성능을 안정적으로 유지할 수 있습니다.

예를 들어, 소켓당 10코어를 가진 2프로세서 호스트(Hyper-Threading 포함 총 40 vCPU 사용 가능)에서 VM의 vCPU를 구성할 때 권장되는 조합은 다음과 같습니다:
| 필요한 vCPU 수 | VM 설정의 가상 소켓 수 | VM 설정의 가상 프로세서당 코어 수 |
| 1 | 1 | 1 |
| …… | ||
| 10 | 1 | 10 |
| 11 | 비최적(non-optimal) | |
| 12 | 2 | 6 |
| …… | ||
| 20 | 2 | 10 |
참고로 무료 ESXi 버전에서는 8개 이상의 vCPU를 가진 VM을 생성할 수 없습니다.
실제 사례를 들면, Microsoft SQL Server 2016 Enterprise Edition을 실행하는 16 vCPU VM(소켓당 2코어씩 8소켓 구성)은 2소켓 × 소켓당 8코어 구성의 VM보다 성능이 떨어집니다.
또한 일부 애플리케이션은 물리적 소켓 수 기준으로 라이선스가 부여된다는 점(구버전 SQL Server가 대표적)을 기억해야 합니다. 경우에 따라 코어 수가 적은 여러 프로세서에 라이선스를 적용하는 것보다 멀티코어 프로세서 1개에 라이선스를 적용하는 것이 더 경제적일 수 있습니다.
마지막으로, 최신 Windows Server 버전은 가상 환경에서 특별한 방식으로 라이선스가 부여되며, VMware vSphere 환경에서도 프로세서 라이선싱과 관련된 몇 가지 고려사항이 존재한다는 점을 참고하시기 바랍니다.