기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만 있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문 종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다. SSOT 결함 둘을 고쳤다. - kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이 「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽 `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다. - virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데 원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다. 기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은 둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더 든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다). 계약을 셋 고쳤다. - kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/** 28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는 것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온 것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수 대조했을 때 가장 가까운 커밋도 28개가 어긋났다). - virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고 재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다. - kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고 넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다. style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져 (실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고, engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고 있었다(Question 기록에서 11.94 → 3.86). verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.3 KiB
id, kind, slug, title, topic, topicName, project, status, questionStatus, studio, sourceRevision, source
| id | kind | slug | title | topic | topicName | project | status | questionStatus | studio | sourceRevision | source | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1b59e6de-16f1-42b2-81bb-01d6198e34bf | QUESTION | qemu-memory-numa-placement | QEMU 메모리는 vCPU 가 도는 NUMA node 와 같은 node 에 있는가 | memory-virtualization | 메모리 가상화 | virtualization | 초안 | OPEN | https://hyeonworks.com/studio/documents/1b59e6de-16f1-42b2-81bb-01d6198e34bf/edit | no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다 |
|
QEMU 메모리는 vCPU 가 도는 NUMA node 와 같은 node 에 있는가
이 호스트의 가상 머신마다 vCPU 가 도는 노드와 메모리가 놓인 노드가 같은지 다른지 적은 값이 없다. NUMA(Non-Uniform Memory Access)는 어느 CPU 가 어느 RAM 에 닿느냐에 따라 접근 비용이 달라지는 구조를 말한다. 이 물음은 지금 배치를 값으로 적는 데까지다. 그 어긋남이 지연을 바꾸는지는 다른 물음이 받는다.
관계
- NUMA 에서는 vCPU 배치와 메모리 배치를 함께 본다 두 배치를 왜 따로 볼 수 없는지를 그 개념이 설명한다.
- 이 호스트의 NUMA 토폴로지는 가상 머신 성능을 고려해야 할 구조인가 노드가 몇 개인지는 그 물음이 받는다. 다중 노드라는 답이 나온 뒤에 이 물음을 연다.
- NUMA remote access 가 이 작업의 지연을 실제로 바꾸는가 여기서 어긋남을 찾으면 그것이 지연까지 바꾸는지는 그쪽이 받는다.
- 메모리 실험 결과에는 Host · VM · Workload 조건을 함께 남긴다 배치를 적을 때 함께 남길 조건을 그 기준이 정한다.
사실
- 게스트 vCPU 는 호스트에서 QEMU 의 vCPU 스레드이고, 그 스레드는 호스트 Linux 스케줄러를 거쳐 호스트 논리 CPU 에서 실행된다.
- 어떤 가상 머신의 vCPU 스레드가 Node 0 의 CPU 에서 도는데 그 가상 머신의 호스트 쪽 physical backing page 가 Node 1 에 있으면 remote access 가 생길 수 있다. 게스트 안에서는 그것도 단순한 memory load 로 보이지만 실제 하드웨어에서는 NUMA interconnect 를 건널 수 있다.
- vCPU 를 특정 노드의 CPU 에 pinning 해도 메모리가 다른 노드에 주로 배치되어 있으면 pinning 이후에도 remote memory access 가 많아질 수 있다. 그래서 vCPU 배치와 메모리 배치를 함께 본다.
- 개념 문서가 이상적인 예로 든 구성은 한 가상 머신의 vCPU 넷이 Node 0 의 CPU 에 붙고 그 가상 머신의 메모리 backing 도 Node 0 RAM 인 경우다.
- 개념 문서는 이 확인에 쓸 명령을 적어 두었다. QEMU 프로세스별 메모리 분포 : numastat -p <QEMU_PID> vCPU 배치 : virsh vcpupin <VM_NAME> 와 virsh vcpuinfo <VM_NAME> 장비 토폴로지 : lscpu 와 numactl --hardware
- 같은 문서의 확인 항목은 numastat 결과를 vCPU 배치와 나란히 놓고 vCPU 와 메모리가 같은 노드인지 다른 노드인지 가르라고 적었다.
- 같은 문서는 vCPU 배치를 따로 묻는 항목도 두고, 그 확인을 CPU 가상화 SSOT 의 pinning/overcommit 관측과 연결한다고 적었다. 그래서 이 주제는 그 물음을 다시 세우지 않았다. vCPU 배치는 CPU 가상화 쪽 물음이 받고 여기서는 메모리 분포와 둘의 어긋남을 받는다.
- 개념 문서의 권장 실험 순서도 vCPU placement 확인을 여덟째에, QEMU NUMA memory distribution 확인을 아홉째에 두어 앞뒤를 갈라 놓았다.
- 이 호스트에서 numastat 을 QEMU 프로세스에 돌린 기록이 없다. vCPU 배치를 적어 둔 기록도 없다.
가정
- 호스트가 다중 NUMA 노드라고 보고 이 실험을 짠다. 노드 수 자체는 CPU 가상화 쪽 물음이 받는다.
- 두 가상 머신이 모두 떠 있는 동안 QEMU 프로세스를 가상 머신마다 가려낼 수 있다고 본다.
- 관측하는 동안 vCPU 스레드가 다른 노드의 CPU 로 옮겨 다니지 않는다고 전제한다. pinning 이 걸려 있지 않으면 이 전제가 깨질 수 있고, 옮겨 다니는지는 CPU 가상화 쪽에서 따로 묻고 있다.
- numastat 이 보고하는 노드별 분포가 그 가상 머신의 게스트 RAM backing 을 대표한다고 본다. QEMU 프로세스에는 게스트 RAM 말고 다른 할당도 들어 있다.
미지수
- 각 가상 머신의 QEMU 메모리가 노드별로 얼마씩 나뉘어 있는지.
- 그 분포가 한 노드로 모여 있는지, 두 노드에 걸쳐 있는지.
- vCPU 스레드가 도는 노드와 메모리가 몰린 노드가 같은지 다른지.
- 두 가상 머신이 같은 노드를 함께 쓰고 있는지.
- 지금 구성에서 memory binding 을 걸 수 있는지. 개념 문서는 두 배치를 함께 보라고만 적었고 이 환경에서 binding 을 바꾸는 방법은 적지 않았다.
제약
- 노드 수를 여기서 다시 재지 않는다. 단일 노드로 확정되면 이 물음은 이 환경에 적용되지 않는다.
- 배치를 바꾸는 일은 이 물음에 들어 있지 않다. 지금 놓여 있는 상태를 적는 것까지다.
- 두 값은 같은 시각에 받아 적는다. 시각이 어긋나면 스케줄러가 vCPU 스레드를 옮긴 뒤의 배치를 앞서 찍은 메모리 분포와 견주게 된다.
- 이 호스트에서 잰 값이 없으므로 다른 장비의 NUMA 배치를 근거로 삼지 않는다.
선택지
1. 가상 머신마다 메모리 분포와 vCPU 배치를 한 번에 받아 적는다
QEMU 프로세스마다 numastat -p 를 돌리고, 같은 시각에 virsh vcpuinfo 와 virsh vcpupin 으로 vCPU 배치를 받아 두 값을 한 표에 넣는다. 어긋남이 있으면 그 표에 그대로 드러나고, 없으면 없다는 것도 같은 표로 남는다.
2. 부하를 준 상태에서 한 번 더 받는다
idle 상태의 배치만 보면 메모리가 아직 실제로 할당되지 않은 구간을 볼 수 있다. 게스트에서 워크로드를 돌린 뒤 같은 두 값을 다시 받으면 실제로 쓰이는 메모리가 어느 노드에 잡히는지까지 나온다.
실행이 두 번으로 늘고 어느 워크로드를 쓸지 먼저 정해야 하는데, 그 선택이 결과를 바꾸기 때문에 Workload 조건을 함께 적는다.
3. 게스트 안에서 numactl 로 확인한다 — 제외
게스트에서도 NUMA 를 볼 수 있으니 게스트 안에서 확인하자는 방법이다. 게스트가 보는 토폴로지는 가상 머신에 노출된 것이다. 이 물음이 찾는 것은 호스트 쪽 physical backing 이 어느 노드에 있느냐이므로, 게스트 쪽 값으로는 그 배치를 알 수 없다. 개념 문서는 큰 가상 머신에서 게스트에게 NUMA 토폴로지 자체를 노출하고 게스트 노드와 호스트 배치가 대응되도록 구성할 수 있다고 적어 두었다. 이 프로젝트의 가상 머신이 그런 구성인지는 그 문서에 없어서, 게스트 값이 호스트 배치를 어디까지 반영하는지도 재기 전에는 모른다.
다음 검증
- 호스트가 다중 NUMA 노드라는 확인을 CPU 가상화 쪽 물음에서 먼저 받는다.
- 가상 머신마다 QEMU 프로세스를 찾아 numastat -p <QEMU_PID> 로 노드별 메모리 분포를 찍는다.
- 같은 시각에 virsh vcpuinfo <VM_NAME> 와 virsh vcpupin <VM_NAME> 로 vCPU 배치를 적는다.
- 두 값을 가상 머신마다 한 표로 나란히 놓고, 노드가 같은지 다른지 적는다.
- Host · VM · Workload 조건을 같은 기록에 남긴다.
닫는 조건 : 노드별 메모리 분포와 vCPU 배치가 가상 머신마다 한 표로 적히면 닫는다. 둘이 같은 노드로 모여 있으면 개념 문서가 경고한 어긋남이 이 환경에는 없다고 적고 닫는다. 어긋나 있으면 그 표가 Case 가 되고, 그 어긋남이 지연까지 바꾸는지는 「NUMA remote access 가 이 작업의 지연을 실제로 바꾸는가」가 받는다. memory binding 을 걸지 말지는 그 뒤 Decision 으로 넘긴다. 단일 NUMA 노드로 나오면 이 물음은 이 환경에 적용되지 않는다고 적고 닫는다.