2012-06-16 34 views
16

Quiero medir el tiempo de ejecución de mi código C++. Ejecutar mi código toma alrededor de 12 horas y quiero escribir esta vez al final de la ejecución de mi código. ¿Cómo puedo hacerlo en mi código?¿Medir el tiempo de ejecución de un código C++?

Sistema operativo: Linux

+1

¿En qué sistema operativo está ejecutando su código? –

+0

Me gusta crear perfiles de varios códigos a la vez. – Puppy

+1

simplemente use el comando 'time' cuando inicie cualquier programa. – Jasen

Respuesta

7

que usa algo como esto en uno de mis proyectos:

#include <sys/time.h> 

struct timeval start, end; 
gettimeofday(&start, NULL); 
//Compute 
gettimeofday(&end, NULL); 
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
     + (end.tv_usec/1000 - start.tv_usec/1000); 

Esto es para milisegundos y funciona tanto para C y C++.

54

Si está utilizando C++ 11 puede utilizar system_clock::now():

auto start = std::chrono::system_clock::now(); 

/* do some work */ 

auto end = std::chrono::system_clock::now(); 
auto elapsed = end - start; 
std::cout << elapsed.count() << '\n'; 

También puede especificar la granularidad de utilizar para la representación de una duración:

// this constructs a duration object using milliseconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 

// this constructs a duration object using seconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::seconds>(end - start); 

Si no puede utilizar C + +11, eche un vistazo a chrono de Boost.

Lo mejor de usar estas bibliotecas estándar es que su portabilidad es muy alta (por ejemplo, ambas funcionan en Linux y Windows). Por lo tanto, no necesita preocuparse demasiado si decide portar su aplicación posteriormente.

Estas bibliotecas también siguen un diseño moderno de C++, a diferencia de los enfoques tipo C.

EDITAR: El ejemplo anterior se puede usar para medir wall-clock time. Sin embargo, esa no es la única manera de medir el tiempo de ejecución de un programa. En primer lugar, podemos distinta entre el tiempo del usuario y del sistema:

  • hora Usuario: El tiempo pasado por el programa que se ejecuta en user space.
  • Tiempo del sistema: Tiempo dedicado por el programa que se ejecuta en el espacio del sistema (o kernel). Un programa ingresa al espacio del núcleo, por ejemplo, al ejecutar un system call.

Según los objetivos, puede ser necesario o no tener en cuenta la hora del sistema como parte del tiempo de ejecución de un programa. Por ejemplo, si el objetivo es simplemente medir una optimización del compilador en el código del usuario, entonces probablemente sea mejor omitir el tiempo del sistema. Por otro lado, si el usuario desea determinar si las llamadas al sistema son una sobrecarga significativa, entonces también es necesario medir el tiempo del sistema.

Además, dado que la mayoría de los sistemas modernos son time-shared, diferentes programas pueden competir por varios recursos informáticos (por ejemplo, CPU). En tal caso, otra distinción se puede hacer:

  • Wall-clock time: Mediante el uso de tiempo de reloj de pared de la ejecución del programa se mide de la misma manera como si estábamos usando un reloj externo (pared). Este enfoque no considera la interacción entre programas.
  • CPU time: En este caso, solo contamos el tiempo que un programa se está ejecutando realmente en la CPU.Si un programa (P1) se programa conjuntamente con otro (P2) y queremos obtener el tiempo de CPU para P1, este enfoque no incluye el tiempo mientras P2 se está ejecutando y P1 está esperando por la CPU (en oposición a el enfoque del tiempo del reloj de pared).

Para la medición de tiempo de CPU, Boost incluye un set of extra clocks:

  • process_real_cpu_clock, captura el tiempo de CPU reloj de pared gastado por el proceso actual.
  • process_user_cpu_clock, captura el tiempo de CPU de usuario consumido por el proceso actual.
  • process_system_cpu_clock, captura el tiempo de CPU del sistema pasado por el proceso actual. Una clase tipo tupla process_cpu_clock, que captura los tiempos reales, de CPU de usuario y de CPU del sistema juntos.
  • A thread_clock reloj constante de hilo que indica el tiempo empleado por el hilo actual (cuando lo admite una plataforma).

Desafortunadamente, C++ 11 no tiene tales relojes. Pero Boost es una biblioteca ampliamente utilizada y, probablemente, estos relojes adicionales se incorporarán a C++ 1x en algún momento. Entonces, si usa Boost, estará listo cuando el nuevo estándar de C++ los agregue.

Finalmente, si desea medir el tiempo que tarda un programa en ejecutar desde la línea de comandos (en lugar de agregar algún código en su programa), puede echarle un vistazo al comando time, tal como lo sugiere @BЈовић. Sin embargo, este enfoque no le permitirá medir partes individuales de su programa (por ejemplo, el tiempo que lleva ejecutar una función).

+0

mi pregunta es: ¿qué hay de las diferencias C++/C++ 11 y las bibliotecas boost? – gaussblurinc

+1

@loldop Creo que la implementación de C++ 11 es un subconjunto de la biblioteca de crono de Boost. Entonces deberían tener una API muy similar (si no es la misma). La ventaja de usar C++ 11 es que no necesita usar Boost (si chrono es la única biblioteca que desea de Boost). – betabandido

10

Puede usar time para comenzar su programa. Cuando termina, imprime agradables estadísticas de tiempo sobre la ejecución del programa. Es fácil configurar qué imprimir. De forma predeterminada, imprime los tiempos de usuario y CPU necesarios para ejecutar el programa.

EDIT: Tomar nota de que todas las medidas desde el código no es correcto, porque su aplicación bloquearse por otros programas, por lo tanto, le da valores erróneos *.

* Por valores equivocados, me refiero a que es fácil de obtener el tiempo necesario para ejecutar el programa, pero que el tiempo varía dependiendo de la carga de CPU durante la ejecución del programa. Para obtener una medición de tiempo relativamente estable, que no dependa de la carga de la CPU, se puede ejecutar la aplicación usando time y usar la CPU como resultado de la medición.

+1

Creo que el bloqueo también es parte del tiempo que tarda el programa en ejecutarse, ¿no? –

+1

@EitanT No, porque la carga de la (s) CPU (s) cambia. La carga actual no tiene que ser la misma que la carga en 1 hora o mañana. –

+0

Ahora veo lo que quieres decir. –

16

Use std::chrono::steady_clock y no std::chrono::system_clock para medir el tiempo de ejecución en C++ 11. La razón es (citando documentación system_clock 's):

en la mayoría de los sistemas, la hora del sistema se puede ajustar en cualquier momento

mientras steady_clock es monótona y es más adecuado para los intervalos de medición:

Clase std :: chrono :: steady_clock representa un reloj monotónico. El tiempo puntos de este reloj no puede disminuir a medida que avanza el tiempo físico. Este reloj no está relacionado con el tiempo del reloj de pared, y es el más adecuado para intervalos de medición .

He aquí un ejemplo:

auto start = std::chrono::steady_clock::now(); 
// do something 
auto finish = std::chrono::steady_clock::now(); 
double elapsed_seconds = std::chrono::duration_cast< 
    std::chrono::duration<double> >(finish - start).count(); 

Un pequeño consejo práctico: si está midiendo el tiempo de ejecución y desea informar segundos std::chrono::duration_cast<std::chrono::seconds> rara vez es lo que necesita, ya que le da toda número de segundos. Para obtener el tiempo en segundos como double, use el ejemplo anterior.

+0

No recibí la sugerencia práctica. ¿No es 'std :: chrono :: duration_cast ' la forma de obtener la diferencia entre dos puntos de tiempo como segundos totales? – Isaac

+0

@Isaac Lo que quiero decir es que 'std :: chrono :: duration_cast ' devolverá 0 si la diferencia es menor que un segundo. Si desea duración como un número de punto flotante, utilice 'double' en lugar de' seconds'. – vitaut

0

También puede probar algunas clases de temporizador que se inician y detienen automáticamente, y recopilar estadísticas sobre el tiempo promedio, máximo y mínimo gastado en cualquier bloque de código, así como el número de llamadas. Estas clases cxx-rtimer están disponibles en GitHub, y ofrecen soporte para usar std :: chrono, clock_gettime(), o boost :: posix_time como fuente de reloj de back-end.

Con estos temporizadores, puede hacer algo como:

void timeCriticalFunction() { 
    static rtimers::cxx11::DefaultTimer timer("expensive"); 
    auto scopedStartStop = timer.scopedStart(); 
    // Do something costly... 
} 

con el cronometraje de las estadísticas escritas a std :: cerr sobre la finalización del programa.

Cuestiones relacionadas