Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

160
Vistas
¿Cuál es la precisión del comando de tiempo incorporado bash?

Tengo un script que mide el tiempo de ejecución de un programa utilizando el time de comando incorporado de bash.

Estoy tratando de entender la precisión de este comando: hasta donde sé, devuelve la precisión en ms, sin embargo, usa la función getrusage() que devuelve un valor en microsegundos. Pero al leer este documento , la precisión real es solo de 10 ms porque getrusage muestrea el tiempo basándose en tics (= 100 Hz). El documento es muy antiguo (menciona Linux 2.2.14 ejecutándose en un Pentium 166Mhz con 96Mb de ram).

¿El time sigue usando getrusage() y ticks de 100 Hz o es más preciso en los sistemas modernos?

La máquina de prueba ejecuta Linux 2.6.32.

EDITAR : esta es una versión ligeramente modificada (que también debería compilarse en la versión anterior de GCC) del código de muru : modifique el valor de la variable 'v', cambie también el retraso entre las medidas para detectar la granularidad mínima. Un valor de alrededor de 500.000 debería desencadenar cambios de 1 ms en una CPU relativamente reciente (primeras versiones de i5/i7 @~2.5Ghz)

 #include <sys/time.h> #include <sys/resource.h> #include <stdio.h> void dosomething(){ long v = 1000000; while (v > 0) v--; } int main() { struct rusage r1, r2; long t1, t2, min, max; int i; printf("t1\tt2\tdiff\n"); for (i = 0; i<5; i++){ getrusage(RUSAGE_SELF, &r1); dosomething(); getrusage(RUSAGE_SELF, &r2); t1 = r1.ru_stime.tv_usec + r1.ru_stime.tv_sec*1000000 + r1.ru_utime.tv_usec + r1.ru_utime.tv_sec*1000000; t2 = r2.ru_stime.tv_usec + r2.ru_stime.tv_sec*1000000 + r2.ru_utime.tv_usec + r2.ru_utime.tv_sec*1000000; printf("%ld\t%ld\t%ld\n",t1,t2,t2-t1); if ((t2-t1 < min) | (i == 0)) min = t2-t1; if ((t2-t1 > max) | (i == 0)) max = t2-t1; dosomething(); } printf("Min = %ldus Max = %ldus\n",min,max); return 0; }

Sin embargo, la precisión está ligada a la versión de Linux: con Linux 3 y superior, la precisión está en nuestro orden, mientras que en Linux 2.6.32 podría ser de alrededor de 1 ms, probablemente dependiendo también de la distribución específica. Supongo que esta diferencia está relacionada con el uso de HRT en lugar de Tick en versiones recientes de Linux.

En cualquier caso la máxima precisión de tiempo es de 1ms en todas las máquinas recientes y no tan recientes.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

El time incorporado de bash todavía usa getrusage(2) . En un sistema Ubuntu 14.04:

 $ bash --version GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. $ strace -o log bash -c 'time sleep 1' real 0m1.018s user 0m0.000s sys 0m0.001s $ tail log getrusage(RUSAGE_SELF, {ru_utime={0, 0}, ru_stime={0, 3242}, ...}) = 0 getrusage(RUSAGE_CHILDREN, {ru_utime={0, 0}, ru_stime={0, 530}, ...}) = 0 write(2, "\n", 1) = 1 write(2, "real\t0m1.018s\n", 14) = 14 write(2, "user\t0m0.000s\n", 14) = 14 write(2, "sys\t0m0.001s\n", 13) = 13 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 exit_group(0) = ? +++ exited with 0 +++

Como muestra la salida de strace , llama a getrusage .

En cuanto a la precisión, la estructura rusage que utiliza getrusage incluye objetos timeval , y timeval tiene una precisión de microsegundos. De la página de manual de getrusage :

 ru_utime This is the total amount of time spent executing in user mode, expressed in a timeval structure (seconds plus microseconds). ru_stime This is the total amount of time spent executing in kernel mode, expressed in a timeval structure (seconds plus microseconds).

Creo que lo hace mejor que 10 ms. Tome el siguiente archivo de ejemplo:

 #include <sys/time.h> #include <sys/resource.h> #include <stdio.h> int main() { struct rusage now, then; getrusage(RUSAGE_SELF, &then); getrusage(RUSAGE_SELF, &now); printf("%ld %ld\n", then.ru_stime.tv_usec + then.ru_stime.tv_sec*1000000 + then.ru_utime.tv_usec + then.ru_utime.tv_sec*1000000 now.ru_stime.tv_usec + now.ru_stime.tv_sec*1000000 + now.ru_utime.tv_usec + now.ru_utime.tv_sec*1000000); }

Ahora:

 $ make test cc test.c -o test $ for ((i=0; i < 5; i++)); do ./test; done 447 448 356 356 348 348 347 347 349 350

Las diferencias reportadas entre llamadas sucesivas a getrusage son 1 µs y 0 (el mínimo). Dado que muestra una brecha de 1 µs, el tick debe tener como máximo 1 µs.

Si tuviera un tic de 10 ms, las diferencias serían cero, o al menos 10000.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda