time() c
tiempo transcurrido rĂ¡pido en Linux (7)
Estoy buscando una manera rápida de obtener el tiempo transcurrido entre dos llamadas de una función en C.
Consideré usar jiffies, pero no están disponibles en userland. Entonces, ¿debería usar getimeofday () o hay alguna forma más rápida de hacerlo?
Solo estoy interesado en el tiempo reducido entre dos llamadas, para usar en una herramienta de referencia.
Lo siguiente me funciona en CentOS 6:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if ! defined(_POSIX_C_SOURCE)
# error "_POSIX_C_SOURCE undefined"
#endif
#if _POSIX_C_SOURCE < 199309L
# error "_POSIX_C_SOURCE < 199309L"
#endif
int main(int, char**){
struct timespec start, stop;
struct timespec stop;
if(clock_gettime(CLOCK_MONOTONIC, &start )) goto err_out;
if(clock_gettime(CLOCK_MONOTONIC, &stop )) goto err_out;
printf("start == {tv_sec: %d, tv_nsec: %d}/n", start.tv_sec, start.tv_nsec);
printf("stop == {tv_sec: %d, tv_nsec: %d}/n", stop.tv_sec, stop.tv_nsec );
printf("stop.tv_nsec - start.tv_nsec == %d/n", stop.tv_nsec - start.tv_nsec);
return EXIT_SUCCESS;
err_out:
perror("clock_gettime");
return EXIT_FAILURE ;
}
... aunque requiere librt
:
$ make dur
cc dur.c -o dur
/tmp/cc1yF58x.o: In function `main'':
dur.c:(.text+0x1c): undefined reference to `clock_gettime''
dur.c:(.text+0x4e): undefined reference to `clock_gettime''
collect2: ld returned 1 exit status
make: *** [dur] Error 1
$ LDFLAGS="-lrt" make dur
cc -lrt dur.c -o dur
$ ./dur
start == {tv_sec: 206247, tv_nsec: 411717209}
stop == {tv_sec: 206247, tv_nsec: 411759791}
stop.tv_nsec - start.tv_nsec == 42582
Me daría el tiempo del procesador a través del clock()
desde la time.h
Para obtener valores útiles, CLOCKS_PER_SEC
en milisegundos a través de CLOCKS_PER_SEC
:
clock_t start = clock();
// [...]
clock_t end = clock();
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;
Sí, gettimeofday () sería suficiente si quieres encontrar el tiempo real transcurrido. Si necesita encontrar el tiempo de CPU, entonces puede usar clock (). En muchos casos, ambos enfoques darían resultados similares (a menos que haya un sueño o algún tipo de espera en el código). Un ejemplo de reloj () se puede encontrar aquí:
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_19.html
Si está en una arquitectura x86 / x64 y está ejecutando en una sola CPU, puede considerar leer el contador de marca de tiempo en la CPU para obtener un recuento de ciclos. Wikipedia tiene más información . Tenga en cuenta que este enfoque es menos útil si su aplicación se ejecuta en múltiples CPU, ya que cada CPU tendrá su propio TSC. También tenga cuidado con la escala de frecuencia si decide convertir ciclos -> unidades de tiempo.
Si su kernel admite gettimeofday()
como vsyscall (llamada de sistema virtual), usar esto será más rápido que llamar a una llamada normal al sistema como clock()
. Vea la presentación de Andrea Arcangeli para obtener información sobre cómo funcionan los vsyscalls.
Una adición tardía, sin embargo, el tiempo disponible en cualquier linux / unix puede ser una forma más liviana de lograr lo que desea. Aquí hay 2 ejemplos
time ls -l stuff*
ls: stuff*: No such file or directory
0.01s real 0.00s user 0.00s system
time -c run_script.csh`
...
real 1m22.38s
user 0m14.67s
sys 0m1.06s
Eche un vistazo a clock_gettime
, que proporciona acceso a temporizadores de alta resolución.