En un post anterior, hemos hablado cómo podemos medir el rendimiento del procesador UltraSPARC T2+. Siguiendo con esta serie de posts, ahora vamos a ver como podemos analizar el comportamiento del procesador SPARC64 VI, en el link anterior podemos ver algunas de las características de este procesador. Podemos destacar, que se trata de un procesador dual-core, con 2 threads hardware por core.
Antes de continuar y tal como comentamos en el post sobre UltraSPARC T2+, es muy recomendable visitar el blog de Ravindra Talashikar.

Es procesdor SPARC64 VI implementa los threads hardware mediante VMT (Virtual Multi-thread), por lo que solo un thread está activo a la vez en un core. Es importante conocer la implementación VMT de este tipo de procesadores, ya que esto nos ayudará a medir el rendimiento del procesador.
Tal como hemos dicho un core gestiona 2 threads hardware, pero solo uno está activo a la vez, esto significa que un procesador cuya velocidad es de 2.1MHz, cada core puede llegar a ajecutar como máximo:
2.1 x 1000 x 1000 = Número máximo de instrucciones por segundo.
En el documento sobre Extensiones de SPARC64 VI podemos encontrar información sobre los distintos contadores disponibles en el procesador, página 212 Multi-thread specific Event Counters. Nos interesan especialmente:
- active_cycle_count, ciclos asignados al thread hardware.
- active_thread_syspend, número de ciclos cuando ambos threads de un core no están ejecutando instrucciones.
Con estos dos contadores, podemos construir una sencilla formula que nos indique el rendimiento del procesador, por la propia naturaleza el SPARC64 VI, los threads no podemos tratarlos de forma separado como hacíamos en el UltraSPARC T2+. Ahora tendremos que analizar el core en su conjunto y no cada thread por separado. Podríamos decir que el rendimeinto de un core sería igual a la suma de los ciclos asignados a los dos threads (active_cycle_count) menos la suma de los contadores active_thread_syspend de los dos threads de un core,
Para un thread el porcentaje de uso sería:
((active_cycle_count – active_thread_syspend) x 100 ) / La mitad del número max de instrucciones por core
Para medir el porcentaje de uso de un core, solo tenemos que sumar el porcentaje de los 2 threads y dividimos entre 2. Un thread hardware de un core, puede ejecutar el solo como máximo el número máximo de instrucciones por segundo, siempre y cuando el otro thread de ese mismo core no ejecute ninguna instrucción. Si los dos threads de un core están al 100% cada uno solo ejecutará la mitad de las instrucciones máximas que puede ejecutar un core.
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: SPARC64 VI & VII
event specification syntax:
[picn=][,attr[n][=]][,[picn=][,attr[n][=]],...]
event0: cycle_counts instruction_counts only_this_thread_active
w_cse_window_empty w_op_stv_wait_nc_pend op_stv_wait
load_store_instructions branch_instructions
floating_instructions impdep2_instructions
prefetch_instructions flush_rs 2iid_use toq_rsbr_phantom
trap_int_vector ts_by_sxmiss both_threads_active
active_cycle_count op_stv_wait_sxmiss eu_comp_wait
op_l1_thrashing swpf_fail_all sx_miss_wait_pf
jbus_cpi_count jbus_reqbus1_busy
event1: cycle_counts instruction_counts instruction_flow_counts
iwr_empty op_stv_wait load_store_instructions
branch_instructions floating_instructions
impdep2_instructions prefetch_instructions rs1 1iid_use
trap_all thread_switch_all only_this_thread_active
active_cycle_count act_thread_suspend cse_window_empty
inh_cmit_gpr_2write if_l1_thrashing swpf_success_all
sx_miss_wait_dm jbus_bi_count lost_softpf_pfp_full
jbus_reqbus0_busy
event2: cycle_counts instruction_counts single_mode_instructions
w_branch_comp_wait w_op_stv_wait_sxmiss_ex op_stv_wait
load_store_instructions branch_instructions
floating_instructions impdep2_instructions
prefetch_instructions 4iid_use flush_rs trap_spill
ts_by_timer active_cycle_count 0iid_use
op_stv_wait_nc_pend 0endop write_op_uTLB sx_miss_count_pf
jbus_cpd_count snres_64 jbus_reqbus3_busy
event3: cycle_counts instruction_counts single_mode_cycle_counts
w_eu_comp_wait w_op_stv_wait_sxmiss op_stv_wait
load_store_instructions branch_instructions
floating_instructions impdep2_instructions
prefetch_instructions 3iid_use trap_int_level
ts_by_data_arrive both_threads_empty active_cycle_count
op_stv_wait_nc_pend op_stv_wait_sxmiss_ex branch_comp_wait
write_if_uTLB sx_miss_count_dm jbus_cpb_count snres_256
lost_softpf_by_abort jbus_reqbus2_busy
event4: cycle_counts instruction_counts d_move_wait w_op_stv_wait
w_fl_comp_wait op_stv_wait load_store_instructions
branch_instructions floating_instructions
impdep2_instructions prefetch_instructions sync_intlk
trap_trap_inst ts_by_if active_cycle_count fl_comp_wait
op_r_iu_req_mi_go sx_read_count_pf jbus_odrbus_busy
sx_miss_count_dm_if jbus_odrbus1_busy
event5: cycle_counts instruction_counts instruction_flow_counts
iwr_empty op_stv_wait load_store_instructions
branch_instructions floating_instructions
impdep2_instructions prefetch_instructions trap_fill
ts_by_intr active_cycle_count flush_rs
cse_window_empty_sp_full op_stv_wait_ex 3endop
if_r_iu_req_mi_go swpf_lbs_hit sx_read_count_dm
jbus_reqbus_busy sx_btc_count jbus_odrbus0_busy
event6: cycle_counts instruction_counts xma_inst w_0endop
w_op_stv_wait_ex op_stv_wait load_store_instructions
branch_instructions floating_instructions
impdep2_instructions prefetch_instructions trap_DMMU_miss
ts_by_suspend ts_by_other active_cycle_count decall_intlk
2endop op_stv_wait_sxmiss op_wait_all dvp_count_pf
sx_miss_count_dm_opex jbus_odrbus3_busy
event7: cycle_counts instruction_counts cse_priority_wait w_d_move
w_cse_window_empty_sp_full op_stv_wait
load_store_instructions branch_instructions
floating_instructions impdep2_instructions
prefetch_instructions regwin_intlk rs1 trap_IMMU_miss
active_cycle_count both_threads_suspended 1endop
op_stv_wait_sxmiss_ex if_wait_all dvp_count_dm
sx_miss_count_dm_opsh jbus_odrbus2_busy
attributes: nouser sys
See the "SPARC64 VI extensions" and "SPARC64 VII extensions" for
descriptions of these events.
De todos los contadores disponibles en el comando cpustat que pueden ser utilizados en los procesadores SPARC64 VI, nos van a interesar:
- active_cycle_count
- act_thread_suspend
Lo siguiente es un ejemplo de la ejecución del comando cpustat.
root@host # cpustat -t -c pic1=act_thread_suspend,pic3=active_cycle_count,sys -c pic1=act_thread_suspend,pic3=active_cycle_count,sys 1 time cpu event %tick pic1 pic3 1.008 168 tick 2162570902 1282410437 1282897885 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 1.008 130 tick 2163776033 383279484 383610644 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 1.008 2 tick 2163553969 2120102957 2163565728 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 1.008 251 tick 2162549377 584650987 589144197 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 2.008 130 tick 2148270412 524002074 524131685 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 2.008 168 tick 2147864206 999846867 1000273984 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 2.008 251 tick 2148005062 1072662447 1072852410 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 2.008 2 tick 2147721610 2104781708 2147715688 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 3.008 130 tick 2148613915 861289690 861594122 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 3.008 251 tick 2148332352 715266764 715965383 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 3.008 168 tick 2148812218 916482914 917347117 # pic1=act_thread_suspend,pic3= active_cycle_count,sys 3.008 2 tick 2148215534 2064217641 2116890140 # pic1=act_thread_suspend,pic3= active_cycle_count,sys ^C root@host #
Según lo que hemos comentado antes, con esta salida podemos averiguar el porcentaje de uso de cada uno de los threads hardware de un core y por lo tanto el porcentaje de uso del core.
El core 1 está formado por los threads hardware 2 y 3, para nuestro ejemplo, solo tenemos que coger la salida del comando cpustat y mediante un script calcular el porcentaje de uso del thread hardware, para la línea:
2.008 2 tick 2147721610 2104781708 2147715688 # pic1=act_thread_suspend,pic3= active_cycle_count,sys
(( 2104781708 – 2147721610 ) x 100 ) / 1074161539 = % uso del thread 2
0 = % uso del thread 3, el cual no aparece en la salida del comando, porque no se está utilizando.
% uso del core = ( 3% + 0%) / 2
Hemos realizado una prueba, sometiendo a la máquina a un periodo de carga para comprobar como aumenta el % de uso del core que estamos analizando, la salida del comando cpustat
root@host # cpustat -t -c pic1=act_thread_suspend,pic3=active_cycle_count,sys -c pic1=act_thread_suspend,pic3=active_cycle_count,nouser,sys 1 | grep " 2 " time cpu event %tick pic1 pic3 1.008 168 tick 2161961978 320334294 320712674 # pic1=act_thread_suspend,pic3=active_cycle_count,sys 1.008 251 tick 2161813749 2082136079 2123271128 # pic1=act_thread_suspend,pic3=active_cycle_count,sys ... 36.005 2 tick 2153397095 16036608 2120222175 # pic1=act_thread_suspend,pic3=active_cycle_count,nouser,sys 37.002 2 tick 2143755997 16052492 2141377900 # pic1=act_thread_suspend,pic3=active_cycle_count,sys 38.003 2 tick 2151078348 3255 2107581823 # pic1=act_thread_suspend,pic3=active_cycle_count,nouser,sys 39.017 2 tick 2178950545 19339186 2176116566 # pic1=act_thread_suspend,pic3=active_cycle_count,sys 40.024 2 tick 2163729641 6445891 2116117804 # pic1=act_thread_suspend,pic3=active_cycle_count,nouser,sys 41.002 2 tick 2102064856 12838681 2099355234 # pic1=act_thread_suspend,pic3=active_cycle_count,sys ...
Para la línea:
40.024 2 tick 2163729641 6445891 2116117804 # pic1=act_thread_suspend,pic3=active_cycle_count,nouser,sys
Para el thread 2 del core el porcentaje de uso sería:
((2116117804 – 6445891 ) x 100 ) / 1074161539 = 196
Para el thread 3 del mismo core el porcentaj de uso es 0, ya que este thread lo hemos desactivado.
El porcentaje de uso del core = (196 + 0 ) / 2 = 98%
corestat
En el blog de Ravindra Talashikar podemos encontrar la utilidad corestat, que consiste en unos scripts en PERL, los cuales devuelven como salida el uso de los cores, threads hardware y pipelines de los distintos procesadores. Los scripts están preparados para calcular los porcentajes de los procesadores UltraSPARC T2+, SPARC64 VI y SPARC64 VII. A menos que te crees tus propios script para tratar la salida del comando cpustat es recomendable que los bajesmos y probemos la utilidad corestat
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.