
Mi PC tiene dos procesadores y sé que cada uno funciona a 1,86 GHz.
Quiero medir el pulso del reloj de los procesadores de mi PC manualmente, y mi idea es simplemente calcular el cociente entre el número de líneas de ensamblador que tiene un programa y el tiempo que mi computadora dedica a ejecutarlo, entonces tengo el número de instrucciones de ensamblaje por tiempo procesado por la CPU (esto es lo que entendí que es un 'ciclo de reloj'). Pensé hacerlo de la siguiente manera:
- Escribo un programa en C y lo convierto en código ensamblador.
- Hago:
$gcc -S my_program.c
, que le indica al compilador gcc que realice todo el proceso de compilación excepto el último paso: transformar my_program.c en un objeto binario. Por lo tanto, tengo un archivo llamado my_program.s que contiene el código fuente de mi programa C traducido a código ensamblador. Cuento las líneas que tiene mi programa (llamemos a este número N). Lo hice:
$ nl -l my_program.s | tail -n 1
y obtuve lo siguiente:1000015 .section .note.GNU-stack,"",@progbits
Es decir, el programa tiene un millón de líneas de código.
- Lo hago:
$gcc my_program.c
para poder ejecutarlo. Hago:
$time ./a.out
("a.out" es el nombre del objeto binario de mi_programa.c) para obtener el tiempo (llamémoslo T) que se emplea en ejecutar el programa y obtengo:real 0m0.059s user 0m0.000s sys 0m0.004s
Se supone que la hora T que estoy buscando es la primera representada en la lista: la "real", porque las demás hacen referencia a otros recursos que se están ejecutando en mi sistema en el mismo momento en que ejecuto ./a.out
.
Entonces tengo N = 1000015 líneas y T = 0,059 segundos. Si realizo una división N/T obtengo que la frecuencia se aproxima a los 17 MHz, lo que evidentemente no es correcto.
Entonces pensé que tal vez el hecho de que haya otros programas ejecutándose en mi ordenador y consumiendo recursos de hardware (sin ir más lejos, el propio sistema operativo) hace que el procesador "divida" su "potencia de procesamiento" y haga que se le vaya el pulso del reloj. Más lento, pero no estoy seguro.
Pero pensé que si esto es correcto, también debería encontrar el porcentaje de recursos de CPU (o memoria) que consume mi programa, porque entonces realmente podría aspirar a obtener un resultado (bien) aproximado sobre la velocidad real de mi CPU.
Y esto me lleva a la cuestión de cómo averiguar el "valor de consumo de recursos" de mi programa. Pensé en el $ top
comando, pero se descarta inmediatamente debido al poco tiempo que tarda mi programa en ejecutarse (0,059 segundos); No es posible distinguir a simple vista ningún pico en el uso de memoria durante este corto tiempo.
Entonces, ¿qué opinas sobre esto? O que me recomiendas hacer? Sé que hay programas que hacen este trabajo que intento hacer, pero prefiero hacerlo usando raw bash porque me interesa hacerlo de la manera más "universal" posible (parece más confiable).
Respuesta1
Eso no funcionará. La cantidad de ciclos de reloj que cada instrucción necesita para ejecutarse (necesitan bastantes, no solo uno) depende en gran medida de la combinación exacta de instrucciones que la rodean y varía según el modelo exacto de CPU. También tienes interrupciones y el kernel y otras tareas que tienen instrucciones ejecutadas se mezclan con las tuyas. Además de eso, la frecuencia cambia dinámicamente en respuesta a la carga y la temperatura.
Las CPU modernas tienen registros específicos del modelo que cuentan el número exacto de ciclos de reloj. Puede leer esto y, utilizando un temporizador de alta resolución, volver a leerlo un período fijo después y comparar los dos para descubrir cuál fue la frecuencia (promedio) durante ese período.