c++ - program - ¿Por qué CLOCKS_PER_SEC no es el número real de relojes por segundo?
time program c++ (5)
Acabo de escribir este breve programa en C ++ para aproximar el número real de tics de reloj por segundo.
#include <iostream>
#include <time.h>
using namespace std;
int main () {
for(int i = 0; i < 10 ; i++) {
int first_clock = clock();
int first_time = time(NULL);
while(time(NULL) <= first_time) {}
int second_time = time(NULL);
int second_clock = clock();
cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "/n";
cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "/n";
}
return 0;
}
Cuando ejecuto el programa, obtengo una salida como esta.
Actual clocks per second = 199139
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 638164
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 610735
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 614835
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 642327
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 562068
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 605767
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 619543
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 650243
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 639128
CLOCKS_PER_SEC = 1000000
¿Por qué el número real de tics de reloj por segundo no coincide con CLOCKS_PER_SEC? Ni siquiera son aproximadamente iguales. ¿Que está pasando aqui?
- CLOCKS_PER_SECOND en POSIX es una constante igual a 1000000.
- CLOCKS_PER_SECOND no debe mostrar la cantidad de reloj en su proceso. Es un número de resolución que puede usar para convertir la cantidad de relojes en una cantidad de tiempo (vea la página del manual para la función clock ())
Por ejemplo si calculas:
(second_clock-first_clock) / CLOCKS_PER_SEC
obtendrá el tiempo total entre la primera y la segunda llamada a la función "clock ()".
Bien duh No sabes hasta qué punto del segundo actual comienzas el tiempo, ¿verdad? Por lo que puede obtener cualquier resultado de 1 a CLOCKS_PER_SEC. Intenta esto en tu bucle interno:
int first_time = time(NULL);
// Wait for timer to roll over before starting clock!
while(time(NULL) <= first_time) {}
int first_clock = clock();
first_time = time(NULL);
while(time(NULL) <= first_time) {}
int second_time = time(NULL);
int second_clock = clock();
cout << "Actual clocks per second = " << (second_clock - first_clock)/(second_time - first_time) << "/n";
cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << "/n";
Ver ideone para el código fuente completo. Informa que los relojes reales por segundo son 1000000, como es de esperar. (Tuve que reducir el número de iteraciones a 2, para que ideone no se agotara).
De la página del hombre del clock(3)
:
POSIX requiere que CLOCKS_PER_SEC sea igual a 1000000 independientemente de la resolución real.
Su implementación parece seguir POSIX al menos en ese sentido.
Ejecutando su programa aquí, me sale
Actual clocks per second = 980000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 990000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 1000000
CLOCKS_PER_SEC = 1000000
o salida similar en una máquina inactiva, y salida como
Actual clocks per second = 50000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 600000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 530000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 580000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 730000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 730000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 600000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 560000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 600000
CLOCKS_PER_SEC = 1000000
Actual clocks per second = 620000
CLOCKS_PER_SEC = 1000000
en una máquina ocupada. Dado que el clock()
mide el tiempo (aproximado) empleado en su programa, parece que lo probó en una máquina ocupada y su programa obtuvo solo alrededor del 60% del tiempo de CPU.
clock
devuelve la cantidad de tiempo empleado en su programa. Hay 1,000,000 tics de reloj por segundo total * . Parece que su programa consumió el 60% de ellos.
Algo más utilizó el otro 40%.
* Bueno, hay virtualmente 1,000,000 de tics de reloj por segundo. El número real está normalizado para que su programa perciba 1,000,000 tics.
Estándar C99
Lo único que dice el borrador estándar de C99 N1256 sobre CLOCKS_PER_SEC
es que:
CLOCKS_PER_SEC que se expande a una expresión con el tipo clock_t (descrito a continuación) que es el número por segundo del valor devuelto por la función de reloj
Como otros lo mencionan, POSIX lo establece en 1 millón, lo que limita la precisión de esto a 1 microsegundo. Creo que esto es solo un valor histórico de los días en que se midieron las frecuencias máximas de CPU en Mega Hertz.