NUMA и топология CCD Ryzen 9 9950X: как размещение vCPU влияет на задержки.
NUMA и топология CCD Ryzen 9 9950X не равнозначны: гость видит NUMA-схему, но не границы L3. Сравнивать нужно размещение vCPU на одной VM внутри CCD, между CCD и без pinning. Результат зависит от нагрузки, BIOS, ядра, QEMU и SMT.
Как определить, какие vCPU находятся на одном CCD?
Сопоставьте логические CPU с ядрами и SMT-сиблингами, затем найдите группы общего L3-кэша. Каждый CCD объединяет восемь ядер с общим L3, номера CPU зависят от хоста, поэтому проверяйте shared_cpu_list. Запишите BIOS, микрокод, ядро и governor.
lscpu -e=CPU,CORE,SOCKET,NODE,CACHE
grep -H . /sys/devices/system/cpu/cpu*/cache/index3/shared_cpu_list
Границы CCD измеримы: в открытом наборе для 9950X с AGESA 1.2.0.2 средняя задержка CAS через общую строку кэша составила 22,4 нс внутри CCD и 79,5 нс между CCD, тогда как numactl границу не покажет.
От физических ядер к vCPU, emulatorpin и vNUMA
vcpupin связывает vCPU с CPU хоста, но не трогает остальные потоки VM: эмулятор QEMU и IOThread закрепляются отдельно. NUMA node гостя должен отражать домен памяти, а не границу L3, иначе межчиплетная задержка смешается с доступом к удалённой RAM.
virsh vcpupin vm-latency
virsh emulatorpin vm-latency
virsh numatune vm-latency
Компактный CCD, разнесённые CCD и свободное планирование
Сравните одну VM в трёх конфигурациях: внутри одного L3, между CCD и без vcpupin. Число vCPU и RAM не меняйте, пиннинг задавайте по физическим ядрам, SMT проверяйте отдельно.
Насколько размещение между CCD увеличивает задержку?
Универсальной прибавки нет: результат зависит от общих данных, синхронизации, памяти и миграций. Сравнивайте одну нагрузку на одном хосте, сохраняя p50, p95, p99 и разброс. Core-to-core тест измеряет обмен между CCD, а не p99 приложения.
Как не принять boost, нагрев или соседнюю VM за эффект CCD
Прогрейте VM, фиксируйте частоту, температуру и %st: performance не удерживает частоту на Ryzen. Чередуйте схемы A–B–C–C–B–A и записывайте фоновые задачи. vNUMA должна совпадать с доменами памяти хоста.
Связь задержки с миграциями, кэш-промахами и удалённой памятью
Возьмите приложение с общей памятью или синхронизацией и микротест обмена. Перед серией проверьте pinning в libvirt и память QEMU, затем снимайте context switches, миграции и NUMA faults. Для cache-misses нужен vPMU. Нормируйте счётчики: рост вместе с p99 причину не доказывает.
perf stat -e context-switches,cpu-migrations,cache-misses \
-- ./test
numastat -p "$(pgrep -fo 'guest=vm-latency')"
Когда пиннинг vCPU улучшает p99?
1. Рабочие потоки часто обращаются к общим данным.
2. Без pinning они мигрируют между группами L3.
3. p99 снижается без потери throughput и роста %st.
Где компактность помогает, а где ограничивает параллелизм
Сведите три схемы в таблицу: медиана p99 по повторам и доверительный интервал разницы. Если интервал пересекает ноль, результат в пределах погрешности. Задачам с независимыми потоками компактность ничего не даёт: обмена между ядрами почти нет, а привязка сужает выбор планировщика.
Как превратить топологию 9950X в правило эксплуатации
До теста задайте порог, например снижение p99 на 10% без потери ops/s. В XML подставьте cpuset и узел.
<vcpu>2</vcpu>
<iothreads>1</iothreads>
<cputune>
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
<emulatorpin cpuset='2'/>
<iothreadpin iothread='1' cpuset='3'/>
</cputune>
<numatune><memory mode='strict' nodeset='0'/></numatune>
Закрепляйте vCPU внутри CCD только если улучшение p99 воспроизводится в повторных прогонах. Если throughput падает или p99 не меняется, оставьте свободное планирование. Топология задаёт гипотезу, решение зависит от VM.