SafeChildren Banner

Havoc Oracle Solaris Experts

lunes, 4 de enero de 2010

Diferencias Procesadores Virtuales, Threads y Cores UltraSPARC

Introducción
Los nuevos diseños de procesadores añaden nuevas formas para resolver los problemas pero, además introducen nuevos retos y configuraciones para poder exprimir al máximo las nuevas arquitecturas.

Uno de los problemas que los nuevos procesadores han introducido son las diferencias entre procesadores virtuales, procesadores reales y threads de ejecución. Vamos a ver si podemos poner un poco de orden y definir las diferencias de cada uno de ellos y cómo nos afectan a la configuración en Solaris.

Antes de comenzar con la explicación de cada uno de ellos, vamos a definir los nombres y así poder saber de qué estamos hablando:
  • Chip: Pastilla de Silicio
  • Hardware Thread: Unidad básica de <planificación> a nivel de procesador
  • Core: Unidad básica de <ejecución> con un procesador
  • SMP: Symmetric Multiprocessing. Arquitectura de computación donde varios procesadores están conectados a través de una memoria compartida
  • CMP: Chip Multriprocessing. Procesador que combina una tecnología de varios <core> en el mismo <chip>
  • CMT: Chip Multithreading. Procesador que permite la ejecución de <hardware thead> en el mismo <chip> que, a su vez, puede contener varios <cores>; O una combinación de ambas tecnologías: Varios <threads> con varios <cores>



Para explicar mejor el funcionamiento de los procesadores, podemos ver las siguientes imágenes donde se explica el funcionamiento de interno de un procesador. Los valores de Compute Cycle son aquellos donde realmente se está realizando un trabajo y Memory Wait son aquellos en los que el procesador está a la espera de IO.


Por lo tanto, el diseño CMT intentará utilizar aquellos Memory Cycle para introducir otros Compute Cycle <hardware thread> y por lo tanto simular varios procesadores dentro del mismo core.

Como podemos ver en la imagen, vamos a llenar aquellos huecos que nuestro procesador está a la espera de IO para poder realizar nuevas tareas y así poder llevar a cabo operaciones en paralelo.

Entonces, realmente tenemos varios procesadores? La verdad es que no. La única solución para tener varios procesadores es tener varios cores o varios chips, aunque en algunos tipos de aplicaciones se puede aproximar.

Tipos de CPU, Cores y Hardware Threads de UltraSPARC
Podemos ver una tabla con las diferentes arquitecturas UltraSPARC con cores, threads y procesadores virtuales. Esta tabla nos servirá posteriormente para poder entender cómo dividir los procesadores virtuales de forma correcta.



Cómo trata Solaris los <Hardware Thread>
Para Solaris los <hardware thread> son tratados como <procesadores virtuales> y por lo tanto si hacemos un <psrinfo> en una máquina UltraSPARC VI con dos CPU veremos el siguiente resultado:
# psrinfo
0       en línea   desde 08/29/2009 05:20:41
1       en línea   desde 08/29/2009 05:20:42
2       en línea   desde 08/29/2009 05:20:42
3       en línea   desde 08/29/2009 05:20:42
8       en línea   desde 08/29/2009 05:20:42
9       en línea   desde 08/29/2009 05:20:42
10      en línea   desde 08/29/2009 05:20:42
11      en línea   desde 08/29/2009 05:20:42
Como podemos ver, para Solaris existen 8 cpu virtuales, que corresponden con: 2CPUx2CORESx2Thread -según la tabla de CPUs-, sin embargo si lanzamos el comando <psrinfo> con la opción <-pv> -physical- veremos la siguiente salida:
# psrinfo -pv
El procesador físico dispone de 4 virtuales virtuales  (0-3)
  SPARC64-VI (portid 1024 impl 0x6 ver 0x93 clock 2150 MHz)
El procesador físico dispone de 4 virtuales virtuales  (8-11)
  SPARC64-VI (portid 1032 impl 0x6 ver 0x93 clock 2150 MHz)
Podemos ver con mayor detalle al ejecutar <prtconf -v> la estrucutra que Solaris asigna a los Hardware Threads y los cores
-snip-
    pseudo-mc, instance #0
        System software properties:
            name='ddi-forceattach' type=int items=1
                value=00000001
        Hardware properties:
            name='mirror-mode' type=int items=1
                value=00000000
        Register Specifications:
            Bus Type=0x4082, Address=0x200, Size=0x0
    cmp (driver not attached)
        core (driver not attached)
            cpu (driver not attached)
            cpu (driver not attached)
        core (driver not attached)
            cpu (driver not attached)
            cpu (driver not attached)
    cmp (driver not attached)
        core (driver not attached)
            cpu (driver not attached)
            cpu (driver not attached)
        core (driver not attached)
            cpu (driver not attached)
            cpu (driver not attached)

    pci, instance #0
        Driver properties:
            name='interrupt-priorities' type=int items=6 dev=none
                value=0000000e.0000000e.0000000e.0000000e.0000000e.0000000e
-snip-
Os preguntaréis el por qué de tanto detalle sobre los Hardware Threads, y a continuación os lo explicaré.

Cómo Dimensionar Correctamente un PSet
Como he comentado antes, para Solaris un  Hardware Thread es igual que un core, sin embargo, estas dos soluciones no son equiparables. En el mejor de los casos un Hardware Thread se comportará como un procesador, pero en el peor -interdependencias entre los threads- no podrán ejecutarse en paralelo.

Con esta premisa en mente, debemos saber que para Dimensionar Correctamente un PSET -Processor Set- debemos seguir siempre la siguiente regla:
Asignar un número de CPU Virtuales múltiplo del número de Hardware Threads que tenga cada core.

Vamos a ver si puedo explicar con más detalle este tema. Si continuamos con el ejemplo de nuestra CPU UltraSPARC64 VI, para Solaris existen 8 vCPU y por lo tanto, puedo crear un PSet de 1 a 8 vCPU. Sin embargo, como hemos comentado, debemos crear PSet -siempre- con múltiplo de número de hardware threads y como son 2 debería ser de: 2, 4, 6 u 8 vCPU. Vemos la siguiente tabla:



Por ejemplo las siguientes combinaciones será correctas:
  • vCPU [0,1,2,3] : pset1
  • vCPU [8,9,10,11] : pset2
Pero las siguientes serán incorrectas:
  • vCPU [0,1,2] : pset1 -el vCPU 2 pertenece al core1-
  • vCPU [3,8,9,10] : pset2 -el vCPU 3 y vCPU 10 a cores diferentes-
Entonces, Cómo sé qué tipo de asignación tengo que hacer?
La verdad es que la única solución para esto es conocer el tipo de CPU que tienes instalada y, por lo tanto, cuántos cores y threads tiene. A partir de ahí, dividir en función del número de threads.


Además, tener en cuenta que si utilizamos la opción dedicated-cpu de una Zona no Global, lo que realmente estamos haciendo es crear un pset, y por lo tanto, deberemos seguir las mismas reglas.


Conclusión
El hecho de que Solaris interprete los Hardware Threads como Procesadores Virtuales hace que el control de los cambios de contexto se produzcan dentro del hardware, además, esto hace que escalar Solaris sea mucho más sencillo. Pero también, introduce el problema de crear Processor Sets siempre con el número de Hardware Threads de cada core y por último, no mezclar Hardware Threads de Cores diferentes. Si tenemos estos pequeños consejos, y ahora que sabemos más sobre el funcionamiento de los procesadores SPARC y cómo Solaris trabaja con ellos, podemos dimensionar mejor nuestros recursos.


Nota: Los gráficos sobre CMT han sido obtenidos de http://developers.sun.com/solaris/articles/chip_multi_thread.html

Referencias

8 comentarios: