2010-06-03 18 views
36

Siempre he usado reloj() para medir cuánto tiempo tomó mi solicitud de principio a fin, como;C: usando el reloj() para medir el tiempo en programas multihilo

int main(int argc, char *argv[]) { 
    const clock_t START = clock(); 

    // ... 

    const double T_ELAPSED = (double)(clock() - START)/CLOCKS_PER_SEC; 
} 

Desde que he empezado a utilizar los hilos POSIX que esto parezca a fallar. Parece que clock() aumenta N veces más rápido con N subprocesos. Como no sé cuántos subprocesos se ejecutarán simultáneamente, este enfoque falla. Entonces, ¿cómo puedo medir cuánto tiempo ha pasado?

+1

Ver [¿Es gettimeofday() garantía de tener una resolución de microsegundos?] (Http://stackoverflow.com/questions/88/is-gettimeofday-guaranteed-to-be-of-microsecondresolution) –

+0

Ver esta respuesta para una solución portátil: http://stackoverflow.com/questions/361363/how-to-measure-time-in-milliseconds-using-ansi-c/37920181#37920181 –

Respuesta

81

clock() mida el tiempo de CPU utilizado por su proceso, no el tiempo del reloj de pared. Cuando tiene varios subprocesos ejecutándose simultáneamente, obviamente puede grabar el tiempo de CPU mucho más rápido.

Si usted quiere saber el tiempo de ejecución del reloj de pared, es necesario utilizar una función apropiada. El único en ANSI C es time(), que generalmente solo tiene una resolución de 1 segundo.

Sin embargo, como dijiste que estás usando POSIX, eso significa que puedes usar clock_gettime(), definido en time.h. El reloj CLOCK_MONOTONIC en particular, es la mejor manera de utilizar para ello:

struct timespec start, finish; 
double elapsed; 

clock_gettime(CLOCK_MONOTONIC, &start); 

/* ... */ 

clock_gettime(CLOCK_MONOTONIC, &finish); 

elapsed = (finish.tv_sec - start.tv_sec); 
elapsed += (finish.tv_nsec - start.tv_nsec)/1000000000.0; 

(Nótese que he hecho el cálculo de elapsed cuidadosamente para asegurar que la precisión no se pierde cuando los intervalos de tiempo muy cortos).

Si su sistema operativo no proporciona CLOCK_MONOTONIC (que se puede comprobar en tiempo de ejecución con sysconf(_SC_MONOTONIC_CLOCK)), entonces se puede utilizar como punto de retorno CLOCK_REALTIME - pero tenga en cuenta que este último tiene la desventaja de que generará resultados incorrectos si la hora del sistema se cambia mientras tu proceso se está ejecutando.

+1

>> Esta es la respuesta correcta cuando se publica por @caf en el océano de muchas respuestas engañosas en SO. Esto es especialmente correcto para los sistemas en tiempo real que sí son compatibles con POSIX. NO usaría el reloj, la hora, el horario del día ni ninguna otra función para este propósito. << – Xofo

+0

¿Qué quiere decir con "cuidadosamente" calcular 'transcurrido'? ¿Tiene alguna importancia el uso de dos declaraciones separadas en lugar de combinarlas en una tarea? – sevko

+2

@sevko: No, podría hacerse en una declaración; a lo que me refiero es a restar ambas porciones de 'segundos' por separado de las porciones de 'nanosegundos', en lugar de (por ejemplo) convertir 'finalizar' y 'iniciar' a valores de coma flotante primero y luego restarlos. – caf

Cuestiones relacionadas