Hace algún tiempo que Sun ha puesto en escena el procesador UltraSPARC T2+, puedes leer una pequeña descripción de este procesador en el siguiente link. El procesador dispone de varios cores (dependiendo del modelo que compres) y cada uno de los cores es capaz de gestionar 8 threads hardware. Solaris trata cada uno de los threads hardware de los cores como si se tratasen de CPUs, en realidad, podemos pensar en CPUs virtuales.
Para entender como podemos medir el rendimiento de un procesador UltraSPARC T2+, es imprescindible leer los posts de Ravindra Talashikar sobre los procesadores T2 y T1, son totalmente recomendables, por no decir imprescindibles.
En este post, lo que vamos a realizar un análisis de cómo funciona el procesador UltraSPARC T2+, qué podemos medir del procesador, para identificar un posible problema de saturación y mostrar unas sencillas pruebas de carga realizadas sobre uno de estos procesadores para ver el rendimiento del procesador sometido a una pruenba de carga.

Este es el esquema básico de la arquitectura de un UltraSPARC T2+. Cada procesador puede tener hasta 8 cores y cada uno de estos cores es capaz de gestionar 8 threads hardware. Solaris, en una máquina que tenga 2 procesadores T2+, verán como 128 CPUs, en realidad está trabajando con cada uno de los threads hardware de los cores como si fuesen CPUs y aquí es donde debemos tener cuidado a la hora de medir el rendimiento de nuestro sistema, ya que NO DISPONEMOS DE 128 PROCESADORES aunque el comando mpstat nos diga lo contrario.
Cada core de un T2+ está organizado de tal forma que cada 4 threads hardware comparten un pipeline, lo que nos da como resultado que cada core dispone de 2 pipelines. El UltraSPARC T2+ es capaz de ejecutar una instrucción por ciclo, esto significa que cada grupo de 4 threads de un core será capaz de ejecutar 1 instrucción por ciclo. Por lo tanto cada core tiene la posibilidad de ejecutar 2 instrucciones por ciclo. En un procesador cuya velocidad sea de 1165 MHz, significa que cada core puede ejecutar:
1165 MHz x 1000 x 1000 = Número de instrucciones por segundo.
Cada core dispone de 2 pipelines, esto significa que el número de instrucciones por segundo es el doble.
2 pipelines x 1165 MHz x 1000 x 1000 = Número de instrucciones por segundo.
Con esta sencilla fórmula podemos calcular el número máximo de instrucciones por segundo que pueden ejecutar todos los cores de nuestra máquina, de esta forma podremos medir cómo de saturado están nuestros procesadores.
cpustat
El comando cpustat nos permite consultar una serie de contadores hardware disponible en los distintos procesadores. Cada procesador tiene sus propios contadores, por lo que es importante, que antes de utilizar el comando cpustat comprobemos cuales son los contadores disponibles en los procesadores de la máquina.
root@host # cpustat -h
Usage:
cpustat [-c events] [-p period] [-nstD] [interval [count]]
-c events specify processor events to be monitored
-n suppress titles
-p period cycle through event list periodically
-s run user soaker thread for system-only events
-t include %tick register
-D enable debug mode
-h print extended usage information
Use cputrack(1) to monitor per-process statistics.
CPU performance counter interface: UltraSPARC T2+
event specification syntax:
[picn=][,attr[n][=]][,[picn=][,attr[n][=]],…]
event[0-1]: Idle_strands Br_completed Br_taken Instr_FGU_arithmetic
Instr_ld Instr_st Instr_sw Instr_other Atomics Instr_cnt
IC_miss DC_miss L2_imiss L2_dmiss_ld ITLB_HWTW_ref_L2
DTLB_HWTW_ref_L2 ITLB_HWTW_miss_L2 DTLB_HWTW_miss_L2
Stream_ld_to_PCX Stream_st_to_PCX CPU_ld_to_PCX
CPU_ifetch_to_PCX CPU_st_to_PCX MMU_ld_to_PCX DES_3DES_op
AES_op RC4_op MD5_SHA-1_SHA-256_op MA_op CRC_TCPIP_cksum
DES_3DES_busy_cycle AES_busy_cycle RC4_busy_cycle
MD5_SHA-1_SHA-256_busy_cycle MA_busy_cycle CRC_MPA_cksum
ITLB_miss DTLB_miss TLB_miss
attributes: hpriv l2ctl emask nouser sys
See the “UltraSPARC T2+ User’s Manual” for descriptions of these
events. Documentation for Sun processors can be found at:
http://www.sun.com/processors/manuals
root@host #
En el ejemplo anterior, podemos ver la salida del comando cpustat ejecutado en una máquina T5140. Entre los contadores disponibles podemos destacar:
- Instr_cnt. Contador de instrucciones.
- IC_miss. Fallos en la cache de instrucciones.
- DC_miss. Fallos en la cache de datos.
- L2_imiss. Fallos en la cache L2 de instrucciones.
- ITLB_miss. Fallos en la TLB de instrucciones.
- DTLB_miss. Fallos en la TLB de datos.
Para medir la saturación del procesador, vamos a utilizar el contador Instr_cnt que nos devuelve el número de instrucciones ejecutadas en un intervalo determinado.
Vamos a ejecutar el comando cpustat para que nos muestre el contado Instr_cnt en intervalos de 1 segundo.
root@jcapp03 # cpustat -t -c pic0=Instr_cnt 1 time cpu event %tick pic0 1.003 8 tick 1152567284 1595 1.003 11 tick 1165544138 1604 1.003 10 tick 1166027871 1604 1.003 9 tick 1166414820 9775 1.013 24 tick 1171174233 426 1.013 25 tick 1170740458 426 1.013 16 tick 1174728555 443 1.013 33 tick 1167129500 426 1.013 17 tick 1174284219 443 1.013 26 tick 1170273285 467 1.013 18 tick 1173889975 426 1.013 35 tick 1166250128 443 1.013 34 tick 1166707237 426 1.013 27 tick 1169819819 451 1.013 19 tick 1173460552 426 1.013 36 tick 1165817219 475 1.013 20 tick 1173041754 426 1.013 12 tick 1176732505 426 1.013 28 tick 1169421351 426 1.013 37 tick 1165409112 426 1.013 13 tick 1176270535 426 1.013 21 tick 1172615507 426 1.013 29 tick 1169000478 426 1.013 14 tick 1175823140 426 1.013 30 tick 1168532323 426 1.013 22 tick 1172181934 426 1.013 31 tick 1168069751 467 1.013 23 tick 1171720735 426 1.013 15 tick 1175328250 20102 1.014 32 tick 1168564242 426 1.023 49 tick 1174019314 426 1.023 48 tick 1174641224 426 1.023 50 tick 1173488538 426 1.023 51 tick 1172939043 426 1.023 52 tick 1172390077 426 1.023 53 tick 1171815546 426 1.023 68 tick 1167820934 14190 1.023 72 tick 1165704565 325052 1.023 67 tick 1168338027 426 1.023 38 tick 1176636092 426 1.023 54 tick 1171010154 426 1.023 64 tick 1145953368 627 1.023 69 tick 1167302036 426 1.023 39 tick 1175947237 426 1.023 70 tick 1166799597 426 1.023 55 tick 1170458103 426 1.023 65 tick 1169289137 603 1.023 71 tick 1166291126 426 1.023 66 tick 1168887198 426 1.033 104 tick 1165315947 426 1.033 88 tick 1173301192 20669 ...
La salida del comando cpustat muestra varias columnas, la primera es el tiempo en el que se ha consultado el contador, la segunda columna muestra el ID de la CPU virtual, recordemos que cada CPU en realidad es un thread hardware. La cuarta columna muestra el número de ciclos ejecutados y la última columna muestra el número de instrucciones ejecutadas durante la muestra.
Para analizar el rendimiento que está dando cada uno de los cores de los procesadores, solo tenemos que agrupar todas las CPUs que ve Solaris en grupos de 8, cada grupo correspondería a un core y cada uno de estos grupos de 8, podríamos dividirlos en 2 grupos de 4 CPUs cada uno.
Podemos decir que un core está saturado cuando la suma de todas las instrucciones ejecutadas por todos sus threads se acercan al número máximo de intrucciones ejecutadas por core:
2 pipelines x 1165 MHz x 1000 x 1000 = Número máximo de instrucciones por segundo ejecutadas por un core.
Prueba de carga
Hemos realizado una sencilla prueba de carga, para ver el comportamiento de uno de los cores del procesador UltraSPARC T2+. La prueba ha sido realizada en una máquina T5140. Se ha creado en el sistema operativo un pool de CPUs, al que hemos asignado 8 CPUs pertenecientes a un mismo core.
root@host # pooladm
system default
string system.comment
int system.version 1
boolean system.bind-default true
string system.poold.objectives wt-load
pool test1
int pool.sys_id 2
boolean pool.active true
boolean pool.default false
int pool.importance 1
string pool.comment
pset ptest1
pset ptest1
int pset.sys_id 1
boolean pset.default false
uint pset.min 1
uint pset.max 16
string pset.units population
uint pset.load 0
uint pset.size 8
string pset.comment
cpu
int cpu.sys_id 5
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 4
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 7
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 6
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 1
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 0
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 3
string cpu.comment
string cpu.status on-line
cpu
int cpu.sys_id 2
string cpu.comment
string cpu.status on-line
...
Para la carga hemos creado el siguiente programa en C.
root@host # cat test_int.c #includevoid main() { int i,n; while(1) { i=0; for(n=0;n<60000;n++) { i=i+1; } } }
La prueba ha consistido en lanzar hasta 8 procesos test_int, uno cada 4 minutos, de esta forma el SO ha asignado una VCPU a cada proceso nuevo. El gráfico siguiente muestra el porcentaje de instrucciones ejecutadas por cada CPU virtual o thread hardware.
De la gráfica podemos obtener como conclusión que el número total de instrucciones por segundo ejecutadas por un core aumenta con cada nuevo thread hardware que comienza a trabajar, lo curioso es que el primer thread hardware que comienza a trabajar lo hace al ~45% de su capacidad, cuando entra el segundo thread hardware, es decir cuando lanzamos el segundo proceso, el uso de los 2 threads hardware baja hasta ~35%, cuando se lanza el tercer proceso, el uso de cada thread hardware baja hasta el ~29% de su capacidad, cuando se lanza el cuarto proceso, los cuatro threads hardware trabajan al ~24% de su capacidad, lo que significa que entre los 4 thread hardware están utilizando al 100% un pipeline. Lo mismo ocurre cuando seguimos lanzando procesos y entra en escena el segundo grupo de threads hardware, lo más curioso es que el primer thread hardware del segundo grupo comienza con una utilización del ~45% de sus capacidad.
Como podemos ver en la línea que representa el número de instrucciones TOTALES ejecutadas por segundo, esta línea crece mas o menos linealmente, hasta llegar al ~90%. en este punto hemos conseguido sacar el máximo de rendimiento al core con el que estamos realizando la prueba.
Conclusión
Para ver el rendimiento de nuestro sistema, debemos analizar el comportamiento de cada uno de los cores que forman parte de los distintos procesadores, esto nos podrá ayudar, tanto a identificar posibles cuellos de botella, como para ayudarnos a tomar decisiones sobre la forma de crecimiento mas optima.
En resumen, con la nueva tecnología de procesadores multicores/multithreads , los administradores de sistemas nos enfrentamos a problemas que nos obligarán a tomar decisiones, dependiendo del nivel de comprensión que tengamos de nuestros sistemas, estas decisiones serán mas o menos acertadas, pero tenemos que tener mucho cuiadado, porque ahora no todo se soluciones con mas CPU.
Algunos derechos reservados. Licencia Creative Commons
Comentarios Recientes
Sobre
Esta plantilla a sido creada con la validacion de CSS y XHTML, por N.Design Studio.Los iconos usados son de Web 2 Mini pack.