En el artículo anterior hablé sobre el Scheduler de Windows y algunas optimizaciones posibles afinitizando tareas a CPUs lógicas poniendo de manifiesto técnicas para mejorar el threading en sistemas Windows 10.
En este me centraré en la Virtualización y como puede beneficiarse de manera importante asignando de forma permanente y definida recursos de CPU a las VM.
Mediante el Administrador de Tareas podemos modificar el comportamiento de un componente crucial de Windows: El Scheduler de Windows 10.
Afinidad y Virtualización
En un Host Windows 10 puedo asignar 4 cores con SMT (un CCX completo con su L3 de 8 MB y 8 threads) a una VM Ubuntu 18.04 LTS en VirtualBox con excelentes resultados en velocidad y sin mermas de prestaciones en el Host Windows 10.
Pondré un ejemplo práctico con VirtualBox y un Guest Ubuntu 18.04 LTS en un Host Windows 10 Pro 1809 x64.
Primero, como base vamos a ver el comportamiento nominal de VirtualBox en Windows 10 Pro.
VirtualBox por defecto en Windows 10
Creamos una VM con 8 cores, 4 GB RAM y demás ajustes:

Ajustes de procesador:

Lanzando la VM y ejecutando alguna tarea ligera obtenemos la siguiente vista en el Administrador de tareas de Windows 10:

Vemos actividad en las CPUs lógicas 1,2,4,6,8,10,12 y 14 (8 en total, tal como hemos definido en VirtualBox):

El resto es actividad ‘residual’ de los procesos del sistema Host Windows 10.
Con htop vemos las 8 CPUs lógicas que he asignado a la VM Ubuntu 18.04 LTS en VirtualBox.

Resumiendo, Windows 10 da libertad total al Scheduler para asignar los threads a las CPUs lógicas disponibles (16), de hecho esta asignación es dinámica y va variando en el tiempo.

Afinidad manual en VirtualBox en Host Windows 10
Debemos ir al Administrador de Tareas del Host Windows 10 Pro, pestaña detalles. Allí buscamos VBoxSVC.exe, click derecho y seleccionamos Establecer Afinidad:

En mi caso, asigno 8 CPUs, de la CPU 7 a la 15 inclusive a VBoxSVC.exe.
En el sistema de pruebas con una CPU AMD Ryzen 7 1700 de 8 cores físicos con 16 CPUs lógicas (threads) opto por dedicar un CCX completo a la VM VirtualBox. Es decir, le asigno:
- 4 cores físicos con sus cachés L1d, L1i y L2 dedicadas.
- 8 MB de caché L3 compartida (CCX1).
- 8 CPUs lógicas gracias al SMT.
Ejecutamos una carga de alta complejidad… (cd /; ls -Rla) en la consola para ver algo de actividad (hay que ser rápido porque corre sobre un 970 Evo de 500 GB…)

Como vemos, solo aparece actividad en las CPUs lógicas correspondientes al segundo CCX (8 a 15 inclusive):

Conclusiones
En sentido estricto hay que valorar si nuestra aplicación va a beneficiarse de llevar a cabo una afinidad manual de los threads a las CPUs lógicas o no.
El ejemplo de la Virtualización es atípico por una cuestión fundamental:
A veces es más eficaz asignar solo CPUs físicas a las VM que asignar el doble de CPUs lógicas. Es un balance que debe de valorar el usuario en función de la máquina, los sistemas Host y Guest y el software.
En este caso quizás la elección perfecta y más balanceada sería la siguiente:
Asignaría 4 CPUs lógicas, todas ellas del segundo CCX a la VM. En este caso los cores lógicos 8, 10, 12 y 14. Quedaría libre el primer CCX completo (8 CPUs lógicas) y las 4 CPUs lógicas impares del segundo CCX.
Todas las transacciones de memoria tencdrían acceso a los recursos completos de los 4 cores físicos del CCX1 y a su caché L3 de 8 MB.