Me refiero a: ¿cómo puedo medir el tiempo de mi CPU gastado en la ejecución de la función y la hora del reloj de pared que se necesita para ejecutar mi función? (Estoy interesado en Linux/Windows y x86 y x86_64). Ver lo que yo quiero hacer (estoy usando C++ aquí, pero yo preferiría C solución):

int startcputime, endcputime, wcts, wcte;

startcputime = cputime();
function(args);
endcputime = cputime();

std::cout << "it took " << endcputime - startcputime << " s of CPU to execute this\n";

wcts = wallclocktime();
function(args);
wcte = wallclocktime();

std::cout << "it took " << wcte - wcts << " s of real time to execute this\n";

Otra pregunta importante: este tipo de medición de tiempo independiente de la arquitectura o no?

  • Me doy cuenta de que quieres hacer esto mediante programación en código, pero aquí va de todos modos: superuser.com/questions/228056/…
  • gracias:) yo sé time en linux, pero como usted escribió, necesito hacerlo directamente en código C
  • En Windows, clock() da a la pared de tiempo y GetProcessTimes da tiempo de cpu. En Linux gettimeofday() da a la pared de tiempo, y clock() da tiempo de cpu.
  • eh! así que es un poco complicado! Voy a intentar escribir algo de código y pegar los resultados más tarde (para win/lin). Pero cualquier otra respuesta es bienvenida! 🙂
  • Si usted puede utilizar C++, boost::auto_cpu_timer (boost.org/libs/timer) es lo que usted necesita. El código se convierte en boost::auto_cpu_timer t; function(args); (sí, no cout, nada y eso es todo, usted consigue la pared de la cpu y me gusta esta característica).
  • FWIW, OpenMP tiene un omp_get_wtime() temporizador de que las medidas de la pared de tiempo y es bastante alta resolución.
  • La verdad es que tengo tanto de wallclock y cpuclocks encapsulado en una API para uno de mis programas (Windows + Linux). Si nadie da una respuesta completa antes de que yo regrese del trabajo, yo voy a publicar aquí.
  • Una vez que se han enfrentado a la dificultad que clock() puede ser fácilmente desbordado. clock_t era un 4 bytes signed integer. Su valor máximo fue de 2^31=2.147e9. CLOCKS_PER_SEC fue de 1000 en Windows y 1000000 en Linux. Así, el tiempo máximo fue de 24.8 días en Windows y el 35,8 min en Linux.

InformationsquelleAutor yak | 2013-07-02

4 Comentarios

  1. 62

    Aquí un copiar-pegar de la solución que funciona tanto en Windows y Linux, así como C y C++.

    Como se ha mencionado en los comentarios, hay un impulso de la biblioteca que hace esto. Pero si usted no puede usar el boost, esto debería funcionar:

    // Windows
    #ifdef _WIN32
    #include <Windows.h>
    double get_wall_time(){
        LARGE_INTEGER time,freq;
        if (!QueryPerformanceFrequency(&freq)){
            // Handle error
            return 0;
        }
        if (!QueryPerformanceCounter(&time)){
            // Handle error
            return 0;
        }
        return (double)time.QuadPart / freq.QuadPart;
    }
    double get_cpu_time(){
        FILETIME a,b,c,d;
        if (GetProcessTimes(GetCurrentProcess(),&a,&b,&c,&d) != 0){
            // Returns total user time.
            // Can be tweaked to include kernel times as well.
            return
                (double)(d.dwLowDateTime |
                ((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001;
        }else{
            // Handle error
            return 0;
        }
    }
    
    // Posix/Linux
    #else
    #include <time.h>
    #include <sys/time.h>
    double get_wall_time(){
        struct timeval time;
        if (gettimeofday(&time,NULL)){
            // Handle error
            return 0;
        }
        return (double)time.tv_sec + (double)time.tv_usec * .000001;
    }
    double get_cpu_time(){
        return (double)clock() / CLOCKS_PER_SEC;
    }
    #endif

    Hay un montón de maneras de implementar estos relojes. Pero aquí está lo que el código anterior utiliza:

    Para Windows:

    Para Linux:


    Y aquí una pequeña demostración:

    #include <math.h>
    #include <iostream>
    using namespace std;
    
    int main(){
    
        // Start Timers
        double wall0 = get_wall_time();
        double cpu0  = get_cpu_time();
    
        // Perform some computation.
        double sum = 0;
    #pragma omp parallel for reduction(+ : sum)
        for (long long i = 1; i < 10000000000; i++){
            sum += log((double)i);
        }
    
        // Stop timers
        double wall1 = get_wall_time();
        double cpu1  = get_cpu_time();
    
        cout << "Wall Time = " << wall1 - wall0 << endl;
        cout << "CPU Time  = " << cpu1  - cpu0  << endl;
    
        // Prevent Code Elimination
        cout << endl;
        cout << "Sum = " << sum << endl;
    
    }

    De salida (12 hilos):

    Wall Time = 15.7586
    CPU Time  = 178.719
    
    Sum = 2.20259e+011
    • Muchas gracias por esto! Sólo dos preguntas más: son aquellos métodos independientes de la arquitectura? Es posible hacer la misma cosa (obtener de la cpu y de la pared del tiempo) usando inline asseembly (y que funcione como, digamos, rdtsc?)
    • No debería ser. Son específicos de OS. Y Windows probablemente utiliza rdtsc() para implementar los contadores de rendimiento. Pero si estuviera en una arquitectura diferente, sería el sistema operativo de trabajo para implementar esas funciones. Tan lejos como lo estas haciendo en ensamblador en línea, es difícil. Tenga en cuenta que rdtsc() por sí mismo no es suficiente para obtener la pared de tiempo, ya que todavía falta algo para dar a cómo muchas garrapatas hay en un segundo. Y yo no soy consciente de nada fuera de la que OS puede dar tiempo de CPU.
    • es el tiempo transcurrido (wall1 – wall0) en cuestión de segundos ?
    • Sí, están todos en cuestión de segundos.
    • clock() funciona bien en Linux, pero no incluye el tiempo empleado en los procesos secundarios (por ejemplo, empezamos por una system() llamada). Si usted necesita para medir también el tiempo de permanencia en el niño los procesos, eche un vistazo a times(), que te ofrece el tiempo de la cpu y del sistema para el proceso actual y para los procesos secundarios. Tenga en cuenta que los relojes por segundo no es CLOCKS_PER_SEC aquí, sino sysconf(_SC_CLK_TCK).
    • Tenga cuidado con QueryPerformanceCounter porque puede saltar hacia adelante inesperadamente por varios segundos, así que usted tiene que comparar constantemente con GetTickCount: Microsoft KB274323.
    • Gran respuesta. Sin embargo, para su Linux/Posix versiones, usted tiene que #include <ctime> o <time.h>, con el fin de utilizar el clock() función y CLOCKS_PER_SEC.
    • Gracias por decírmelo. Lo he añadido.
    • Exactamente el mismo código en mi máquina windows (64 bits) que se ejecute un código cuda: la Pared de Tiempo = 0.251269 Tiempo de CPU = 0.0625 ¿por qué todo lo contrario? Yo esperaba que el tiempo de la CPU para ser más grande. Hay algunos hilos generado demasiado. Si me quedo nvidia visual profiler, entonces el tiempo de la CPU se convierte en cero, mientras que en la pared se mantiene igual.
    • Yo no sé mucho acerca de CUDA. Pero si es la CPU, entonces parece que el proceso se bloquee o la tarea a cabo.

  2. 27

    C++11. Mucho más fácil escribir!

    Uso std::chrono::system_clock para reloj de pared y std::clock de reloj de cpu
    http://en.cppreference.com/w/cpp/chrono/system_clock

    #include <cstdio>
    #include <ctime>
    #include <chrono>
    
    .... 
    
    std::clock_t startcputime = std::clock();
    do_some_fancy_stuff();
    double cpu_duration = (std::clock() - startcputime) / (double)CLOCKS_PER_SEC;
    std::cout << "Finished in " << cpu_duration << " seconds [CPU Clock] " << std::endl;
    
    
    auto wcts = std::chrono::system_clock::now();
    do_some_fancy_stuff();
    std::chrono::duration<double> wctduration = (std::chrono::system_clock::now() - wcts);
    std::cout << "Finished in " << wctduration.count() << " seconds [Wall Clock]" << std::endl;

    Et voilà, fácil y portátil! No hay necesidad de #ifdef _WIN32 o LINUX!

    Incluso se podría usar chrono::high_resolution_clock si necesita más precisión
    http://en.cppreference.com/w/cpp/chrono/high_resolution_clock

    • ¿por qué utilizar auto para wcts luego std::chrono::duration<double> para wctduration?
    • Por desgracia std::clock trabajo en Windows de una manera no estándar, por lo que «portable» es un poco demasiado optimista.
  3. 13

    Para dar un ejemplo concreto de @labio sugerencia de uso boost::timer si puedes (probado con el Impulso 1.51):

    #include <boost/timer/timer.hpp>
    
    //this is wallclock AND cpu time
    boost::timer::cpu_timer timer;
    
    ... run some computation ...
    
    boost::timer::cpu_times elapsed = timer.elapsed();
    std::cout << " CPU TIME: " << (elapsed.user + elapsed.system) / 1e9 << " seconds"
              << " WALLCLOCK TIME: " << elapsed.wall / 1e9 << " seconds"
              << std::endl;
    • Cuál es el tiempo total?
    • «total» en que sentido ? El tiempo de CPU es generalmente suman a lo largo de todos los hilos/núcleos (suma de la duración de cada núcleo de la CPU estaba ocupado ejecutando el código), wallclock tiempo es el tiempo que había que esperar hasta que el código se completa. Para el código que se ejecuta en más de un núcleo de la CPU, el tiempo de la CPU puede ser mayor que el wallclock tiempo.
    • Ya he averiguado es la hora del reloj de pared.
    • No, usted no figura tanto son ‘total’ uno es tiempo de reloj de pared y el otro es el tiempo de la cpu.
  4. -1

    Utilizar el clock método en tiempo.h:

    clock_t start = clock();
    /* Do stuffs */
    clock_t end = clock();
    float seconds = (float)(end - start) / CLOCKS_PER_SEC;

    Por desgracia, este método devuelve el tiempo de la CPU en Linux, pero devuelve la hora del reloj de pared en Windows (gracias a los comentaristas de esta información).

    • y me da que tiempo? reloj de pared de tiempo o el tiempo de cpu?
    • Mide el tiempo de CPU, no la hora del reloj de pared si eso es lo que están buscando.
    • En realidad, clock() da tiempo de cpu en Linux, y la pared de vez en Windows.
    • Estoy buscando tanto;) saludos para esto, así que ahora tengo que buscar a sólo una hora del reloj de pared 😛
    • ¿estás 100% seguro? se le puede dar cualquier código de las muestras (para win/lin)? cualquier documentación acerca de este problema?
    • Sólo probarlo. Verás que clock() da tiempo real, independientemente de la actividad de subproceso.
    • Yo estaba de mal, lo siento. Dejar a Windows para atornillar con las cosas.
    • se supone que devuelve el tiempo de la CPU según la norma ISO; MS documentación establece claramente que devuelve la hora del reloj de pared en Windows, aunque…

Dejar respuesta

Please enter your comment!
Please enter your name here