Microsoft MVP성태의 닷넷 이야기
Windows: 280. Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root) [링크 복사], [링크+제목 복사],
조회: 2123
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 

(시리즈 글이 12개 있습니다.)
Windows: 63. 윈도우 서버 2012 - Hyper-V의 새로운 기능 Live Migration
; https://www.sysnet.pe.kr/2/0/1356

개발 환경 구성: 211. Hyper-V - Generation 2 유형의 VM 생성 시 ISO 부팅이 안된다면?
; https://www.sysnet.pe.kr/2/0/1603

개발 환경 구성: 236. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법
; https://www.sysnet.pe.kr/2/0/1742

개발 환경 구성: 317. Hyper-V 내의 VM에서 다시 Hyper-V를 설치: Nested Virtualization
; https://www.sysnet.pe.kr/2/0/11218

개발 환경 구성: 405. Hyper-V 가상 머신에서 직렬 포트(Serial Port, COM Port) 사용
; https://www.sysnet.pe.kr/2/0/11720

.NET Framework: 798. C# - Hyper-V 가상 머신의 직렬 포트와 연결된 Named Pipe 간의 통신
; https://www.sysnet.pe.kr/2/0/11722

디버깅 기술: 169. Hyper-V의 VM에 대한 메모리 덤프를 뜨는 방법
; https://www.sysnet.pe.kr/2/0/12284

개발 환경 구성: 608. Hyper-V 가상 머신에 Console 모드로 로그인하는 방법
; https://www.sysnet.pe.kr/2/0/12859

개발 환경 구성: 664. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/13246

Windows: 259. Hyper-V Generation 1 유형의 VM을 Generation 2 유형으로 바꾸는 방법
; https://www.sysnet.pe.kr/2/0/13564

개발 환경 구성: 718. Hyper-V - 리눅스 VM에 새로운 디스크 추가
; https://www.sysnet.pe.kr/2/0/13706

Windows: 280. Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root)
; https://www.sysnet.pe.kr/2/0/13901




Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root)

Windows 11 Hyper-V에 올린 VM의 경우, 속성 창의 "Processor" 정보를 보면 이런 경고가 나옵니다.

hyperv_cpu_is_zero_2.png

Hyper-V is not configured to enable processor resource controls.

Learn more about Hyper-V processor configuration options.

반면, Windows Server 2025의 Hyper-V에 올린 VM의 경우, 이런 경고가 나오지 않습니다. 이유는 간단한데요, Windows 11 Hyper-V의 경우엔 Root scheduler, Windows Server의 경우에는 Core Scheduler를 기본으로 채택하고 있기 때문입니다.

따라서, Windows 11의 경우에도 Core 또는 Classic Scheduler를 사용하도록 설정하면 해당 경고가 나오지 않는데, 딱히 권장하지는 않으므로 그냥 경고를 무시하면 됩니다. (이유는 아래에서 설명합니다.)

참고로, scheduler 유형은 bcdedit 명령을 통해서 설정할 수 있고,

// 관리자 권한 요구

C:\Windows\System32> bcdedit /set hypervisorschedulertype Core

* 주의: hypervisorschedulertype을 바꾸고 나서 재부팅하기 전에 현재 실행 중인 모든 VM을 (저장이 아닌) 중지해야 합니다.
* 그렇지 않으면 재부팅 후 VM이 로딩되지 않습니다.

저렇게 명시적으로 설정한 경우에는 마찬가지로 bcdedit 명령어를 통해 확인까지 가능합니다.

C:\Windows\System32> bcdedit

Windows Boot Manager
--------------------
identifier              {bootmgr}
...[생략]...

Windows Boot Loader
-------------------
identifier              {current}
...[생략]...
hypervisorlaunchtype    Auto
hypervisorschedulertype Core

하지만 명시적으로 설정하지 않은 경우에는 hypervisorschedulertype 항목이 출력되지 않으므로 알 수가 없는데요, 이럴 때는 이벤트 로그를 통해 확인할 수 있다고 합니다.

PS C:\temp> Get-WinEvent -FilterHashTable @{ProviderName="Microsoft-Windows-Hyper-V-Hypervisor"; ID=2} -MaxEvents 1
   ProviderName: Microsoft-Windows-Hyper-V-Hypervisor

TimeCreated                      Id LevelDisplayName Message
-----------                      -- ---------------- -------
2025-02-13 오전 9:55:36             2 Information      Hypervisor scheduler type is 0x4. 

위의 경우 0x4로 나오는데 이것은 "root scheduler"를 사용하는 경우로, 기타 나올 수 있는 숫자 유형은 다음과 같습니다.

1 = Classic scheduler, SMT disabled
2 = Classic scheduler
3 = Core scheduler
4 = Root scheduler




기왕에 이렇게 됐으니, 이참에 classic, core, root 방식의 차이점을 알고 넘어가는 것도 좋겠습니다. ^^ 검색해 보면, 아래의 글이 나오는데,

What is the Hyper-V Core Scheduler?
; https://www.altaro.com/hyper-v/hyper-v-core-scheduler/

간단하게 정리해 볼까요? ^^

우선 (그동안 기본적으로 사용했던) Classic은 Host/VM의 모든 스레드가 동등하게 CPU 자원을 나눠가지는 방식입니다. 그런데, 이 방식에는 한 가지 문제점이 있습니다.

바로, Hyper-Threading이 활성화된 Core의 경우 Cache를 공유하고 있어 서로 다른 VM의 스레드가 1개의 Core에서 동시에 실행될 때 Cache의 내용을 어느 한 쪽이 위/변조할 수 있다는 것입니다. (아마도, Spectre/Meltdown과 같은 Side-Channel 공격과 관련해 한창 이슈가 되었던 그 시절에 VM의 이런 문제도 떠오르지 않았나 싶습니다.)

그래서, 이에 대한 해법으로 내놓은 방식이 "Core Scheduler"입니다. cache 공유를 막자는 이유이므로, Core Scheduler는 VM의 스레드를 물리적인 Core마다 1개만 할당하는 방식입니다. 그러니까, 아래의 그림처럼 서로 다른 VM의 스레드가 코어를 공유하지 않게 된 것입니다.

// (X) Core Scheduler에서는 이렇게 서로 다른 VM이 1개의 Core를 공유하지 못함
┏────────────────────────────────────┓
│       Pyhsical Core (HT-enabled)   │
│  ┏─────────────┓  ┏─────────────┓  │
│  │ VM1         │  │ VM2         │  │
│  │ Thread 1    │  │ Thread 1    │  │
│  ┗─────────────┛  ┗─────────────┛  │
┗────────────────────────────────────┛

심지어, 같은 VM의 스레드도 Core를 공유하지 못합니다. 왜냐하면, VM은 호스트 측의 Core를 마치 Hyper-Threading이 비활성화된 것처럼 사용하기 때문에 아래와 같은 식으로 스레드가 배분되는 것입니다.

// Core Scheduler의 경우 개별 VM 스레드마다 1개의 Core로 스케줄링
┏────────────────────────────────────┓  ┏────────────────────────────────────┓
│       Pyhsical Core (HT-enabled)   │  │       Pyhsical Core (HT-enabled)   │
│  ┏─────────────┓  ┏─────────────┓  │  │  ┏─────────────┓  ┏─────────────┓  │
│  │ VM1         │  │             │  │  │  │ VM1         │  │             │  │
│  │ Thread 1    │  │             │  │  │  │ Thread 1    │  │             │  │
│  ┗─────────────┛  ┗─────────────┛  │  │  ┗─────────────┛  ┗─────────────┛  │
┗────────────────────────────────────┛  ┗────────────────────────────────────┛

이상하다고 여길 수 있지만, 달리 생각해 호스트 측의 BIOS 설정에서 Hyper-Threading을 비활성화하는 것과 같은 효과라고 보시면 됩니다. 즉, Classic Scheduler 방식만 있을 때는 굳이 VM에 HT를 활성화하지 않아도 Hyper-V가 평등하게 CPU 자원을 나눠주기 때문에 문제가 없었는데, 그것이 Core Scheduler로 바뀌면서 VM 측에 HT를 인지하도록 설정하는 것이 필요해진 것입니다.

어쨌든, 비효율적이죠? 실제로 이런 상황이 있어서 아래와 같은 질문이 나온 것입니다.

Windows Server 2019 HyperV strange CPU usage pattern
; https://learn.microsoft.com/en-us/answers/questions/133565/windows-server-2019-hyperv-strange-cpu-usage-patte

그리고 위의 질문에 있는 이미지가 이 상황을 잘 설명해 줍니다.

smt_enabled_1.png

이 문제를 해결하려면, 가상 머신이 HT를 인지하도록 설정해야 하는데 그래서 Hyper-V는 이와 관련해 별도로 HwThreadCountPerCore 옵션을 제공합니다.

Enable SMT in guest VMs
; https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/manage/manage-hyper-v-scheduler-types#virtual-machine-cpu-resource-controls-and-the-root-scheduler

How to Enable Processor Resource Controls in Hyper-V
; https://huybien.com/how-to-enable-processor-resource-controls-in-hyper-v/

Set-VMProcessor -VMName <VMName> -HwThreadCountPerCore <n>, where <n>

// 0: Inherit SMT topology from the host
// 1: Non-SMT
// Values > 1: the desired number of SMT threads per core. May not exceed the number of physical SMT threads per core.

결국 (근래에는) 대개의 경우 아래와 같은 정도로 설정한다고 보면 됩니다.

// 대개의 경우, 호스트 측은 HT를 활성화시켰을 것이고, VM은 호스트의 설정을 따라가도록 설정
PS C:\Windows\System32> Set-VMProcessor -VMName win11en -HwThreadCountPerCore 0

// 대상 VM의 SMT 설정 확인
PS C:\Windows\System32> (Get-VMProcessor -VMName win11en).HwThreadCountPerCore
0

이렇게 되면 VM 측의 스레드가 2의 배수라면 같은 Core에서 실행될 수 있습니다.

// (O) HwThreadCountPerCore == 0 또는 2인 경우 같은 VM에 있는 스레드라면 같은 Core를 공유할 수 있음
┏────────────────────────────────────┓ ┏────────────────────────────────────┓
│       Pyhsical Core (HT-enabled)   │ │       Pyhsical Core (HT-enabled)   │
│  ┏─────────────┓  ┏─────────────┓  │ │  ┏─────────────┓  ┏─────────────┓  │
│  │ VM1         │  │ VM1         │  │ │  │ VM1         │  │             │  │
│  │ Thread 1    │  │ Thread 2    │  │ │  │ Thread 3    │  │             │  │
│  ┗─────────────┛  ┗─────────────┛  │ │  ┗─────────────┛  ┗─────────────┛  │
┗────────────────────────────────────┛ ┗────────────────────────────────────┛




마지막으로 (Windows 10 1803부터 지원하기 시작한) root scheudler는 위의 내용과 상관없이 이해할 수 있는데요, 이것은 스케줄링 권한을 루트 파티션에 맡겨 호스트 OS에 CPU 자원을 좀 더 할당하게 해줍니다.

이런 방식으로 인해, root scheduler는 서버 유형의 환경에서는 지원하지 않는다고 합니다.

// https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/manage/manage-hyper-v-scheduler-types#select-the-hypervisor-scheduler-type-on-windows-server

The hypervisor root scheduler isn't supported on Windows Server Hyper-V at this time. Hyper-V administrators shouldn't attempt to configure the root scheduler for use with server virtualization scenarios.


그러고 보니, 제 테스트 머신 중에 "root scheduler"로 나온 것은 Windows 11이었고, Windows Server 2022/2025"는 모두 "core scheduler"였습니다.

현실적으로, 클라이언트용 PC라면 VM 서비스를 위한 것은 아니므로 root scheduler가 맞는 선택일 것입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 3/9/2025]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 16  17  18  19  20  [21]  22  23  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13413정성태9/14/202311953닷넷: 2143. C# - 시스템 Time Zone 변경 시 이벤트 알림을 받는 방법
13412정성태9/14/202315457닷넷: 2142. C# 12 - 인라인 배열(Inline Arrays) [1]
13411정성태9/12/202311781Windows: 252. 권한 상승 전/후 따로 관리되는 공유 네트워크 드라이브 정보 [1]
13410정성태9/11/202313247닷넷: 2141. C# 12 - Interceptor (컴파일 시에 메서드 호출 재작성) [1]
13409정성태9/8/202312523닷넷: 2140. C# - Win32 API를 이용한 모니터 전원 끄기
13408정성태9/5/202312111Windows: 251. 임의로 만든 EXE 파일을 포함한 ZIP 파일의 압축을 해제할 때 Windows Defender에 의해 삭제되는 경우
13407정성태9/4/202311938닷넷: 2139. C# - ParallelEnumerable을 이용한 IEnumerable에 대한 병렬 처리
13406정성태9/4/202311719VS.NET IDE: 186. Visual Studio Community 버전의 라이선스
13405정성태9/3/202312793닷넷: 2138. C# - async 메서드 호출 원칙
13404정성태8/29/202312956오류 유형: 876. Windows - 키보드의 등호(=, Equals sign) 키가 눌리지 않는 경우
13403정성태8/21/202311623오류 유형: 875. The following signatures couldn't be verified because the public key is not available: NO_PUBKEY EB3E94ADBE1229CF
13402정성태8/20/202311830닷넷: 2137. ILSpy의 nuget 라이브러리 버전 - ICSharpCode.Decompiler
13401정성태8/19/202311722닷넷: 2136. .NET 5+ 환경에서 P/Invoke의 성능을 높이기 위한 SuppressGCTransition 특성 [1]
13400정성태8/10/202311444오류 유형: 874. 파이썬 - pymssql을 윈도우 환경에서 설치 불가
13399정성태8/9/202310399닷넷: 2135. C# - 지역 변수로 이해하는 메서드 매개변수의 값/참조 전달
13398정성태8/3/202313390스크립트: 55. 파이썬 - pyodbc를 이용한 SQL Server 연결 사용법
13397정성태7/23/202312373닷넷: 2134. C# - 문자열 연결 시 string.Create를 이용한 GC 할당 최소화
13396정성태7/22/202311789스크립트: 54. 파이썬 pystack 소개 - 메모리 덤프로부터 콜 스택 열거
13395정성태7/20/202311069개발 환경 구성: 685. 로컬에서 개발 중인 ASP.NET Core/5+ 웹 사이트에 대해 localhost 이외의 호스트 이름으로 접근하는 방법
13394정성태7/16/202310424오류 유형: 873. Oracle.ManagedDataAccess.Client - 쿼리 수행 시 System.InvalidOperationException
13393정성태7/16/202311144닷넷: 2133. C# - Oracle 데이터베이스의 Sleep 쿼리 실행하는 방법
13392정성태7/16/202310737오류 유형: 872. Oracle - ORA-01031: insufficient privileges
13391정성태7/14/202311142닷넷: 2132. C# - sealed 클래스의 메서드를 callback 호출했을 때 인라인 처리가 될까요?
13390정성태7/12/202311080스크립트: 53. 파이썬 - localhost 호출 시의 hang 현상
13389정성태7/5/202311430개발 환경 구성: 684. IIS Express로 호스팅하는 웹을 WSL 환경에서 접근하는 방법
13388정성태7/3/202311849오류 유형: 871. 윈도우 탐색기에서 열리지 않는 zip 파일 - The Compressed (zipped) Folder '[...].zip' is invalid. [1]파일 다운로드1
... 16  17  18  19  20  [21]  22  23  24  25  26  27  28  29  30  ...