Beste Timing-Methode in C?

Lesezeit: 4 Minuten

Benutzeravatar von lillq
lillq

Was ist der beste Weg, um einen Codeabschnitt mit hoher Auflösung und Portabilität zu timen?

/* Time from here */
ProcessIntenseFunction();
/* to here. */

printf("Time taken %d seconds %d milliseconds", sec, msec);

Gibt es eine Standardbibliothek, die eine plattformübergreifende Lösung hätte?

Ich denke das sollte funktionieren:

#include <time.h>

clock_t start = clock(), diff;
ProcessIntenseFunction();
diff = clock() - start;

int msec = diff * 1000 / CLOCKS_PER_SEC;
printf("Time taken %d seconds %d milliseconds", msec/1000, msec%1000);

  • Dies ist eigentlich gut, da es Ihnen eher CPU-Zeit als verstrichene Zeit gibt (verstrichene Zeit könnte von anderen Prozessen beeinflusst werden). Denken Sie nur daran, dass eine Zahl von 10 Sekunden nicht unbedingt bedeutet, dass es in einer verstrichenen Zeit von 10 Sekunden ausgeführt wird, da es möglicherweise E / A-Überlegungen gibt. Dies misst die CPU NUR.

    – paxdiablo

    20. Januar 2009 um 1:22 Uhr

  • Ich habe dies hunderte Male verwendet und ist die beste/einfachste Lösung für diese Frage

    – Gerhard

    21. Januar 2009 um 6:18 Uhr

  • Sie können das alles sogar in ein Makro packen, wenn Sie häufig mehrere Dinge zeitlich messen: #define timing(a) start=clock(); a; diff = Uhr () – Start; msec = diff * 1000 / CLOCKS_PER_SEC; printf(“msec: %d\n”,msec); und dann aufrufen: timing(IntenseFunc1())

    – eqzx

    26. Februar 2012 um 19:03 Uhr


  • clock_t ist normalerweise lang und CLOCKS_PER_SEC ist 1000000. In diesem Fall führt eine Differenz von mehr als 4 Sekunden zu einem Überlauf und seltsamen Ergebnissen

    – Begelfor

    5. März 2014 um 13:22 Uhr

  • @paxdiablo Ich bekomme damit völlig gleichwertige Ergebnisse wie mit gettimeofday(), bin mir nicht sicher, was du hier sagst.

    – Benutzer3467349

    21. Oktober 2014 um 21:47 Uhr


gettimeofday() wird wahrscheinlich das tun, was Sie wollen.

Wenn Sie Intel-Hardware verwenden, erfahren Sie hier, wie Sie den CPU-Echtzeit-Befehlszähler lesen. Es zeigt Ihnen die Anzahl der seit dem Start des Prozessors ausgeführten CPU-Zyklen an. Dies ist wahrscheinlich der feinste, niedrigste Overhead-Zähler, den Sie für die Leistungsmessung erhalten können.

Beachten Sie, dass dies die Anzahl der CPU-Zyklen ist. Unter Linux können Sie die CPU-Geschwindigkeit aus /proc/cpuinfo abrufen und dividieren, um die Anzahl der Sekunden zu erhalten. Es ist ziemlich praktisch, dies in ein Doppel umzuwandeln.

Wenn ich das auf meiner Box starte, bekomme ich

11867927879484732
11867927879692217
it took this long to call printf: 207485

Hier ist die Intel-Entwicklerleitfaden das gibt Tonnen von Details.

#include <stdio.h>
#include <stdint.h>

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}

gettimeofday gibt die Zeit innerhalb der Auflösung der Systemuhr auf Mikrosekunden genau zurück. Vielleicht möchten Sie sich auch die ansehen Hochauflösende Timer Projekt auf SourceForge.

ich benutze SDL_GetTicks von dem SDL-Bibliothek.

Wenn Sie keine CPU-Zeit möchten, suchen Sie meiner Meinung nach die timeval-Struktur.

Ich verwende das Folgende zur Berechnung der Ausführungszeit:

int timeval_subtract(struct timeval *result,                                                                                                                                        
                     struct timeval end,                                                                                                                                                 
                     struct timeval start)                                                                                                                                               
{                                                                                                                                                                                   
        if (start.tv_usec < end.tv_usec) {                                                                                                                                          
                int nsec = (end.tv_usec - start.tv_usec) / 1000000 + 1;                                                                                                             
                end.tv_usec -= 1000000 * nsec;                                                                                                                                      
                end.tv_sec += nsec;                                                                                                                                                 
        }                                                                                                                                                                           
        if (start.tv_usec - end.tv_usec > 1000000) {                                                                                                                                
                int nsec = (end.tv_usec - start.tv_usec) / 1000000;                                                                                                                 
                end.tv_usec += 1000000 * nsec;                                                                                                                                      
                end.tv_sec -= nsec;                                                                                                                                                 
        }                                                                                                                                                                           

        result->tv_sec = end.tv_sec - start.tv_sec;                                                                                                                                 
        result->tv_usec = end.tv_usec - start.tv_usec;                                                                                                                              

        return end.tv_sec < start.tv_sec;                                                                                                                                           
}                                                                                                                                                                                   

void set_exec_time(int end)                                                                                                                                                         
{                                                                                                                                                                                   
        static struct timeval time_start;                                                                                                                                           
        struct timeval time_end;                                                                                                                                                    
        struct timeval time_diff;                                                                                                                                                   

        if (end) {                                                                                                                                                                  
                gettimeofday(&time_end, NULL);                                                                                                                                      
                if (timeval_subtract(&time_diff, time_end, time_start) == 0) {                                                                                                      
                        if (end == 1)                                                                                                                                               
                                printf("\nexec time: %1.2fs\n",                                                                                                                     
                                        time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f));                                                                                       
                        else if (end == 2)                                                                                                                                          
                                printf("%1.2fs",                                                                                                                                    
                                        time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f));                                                                                       
                }                                                                                                                                                                   
                return;                                                                                                                                                             
        }                                                                                                                                                                           
        gettimeofday(&time_start, NULL);                                                                                                                                            
}                                                                                                                                                                                   

void start_exec_timer()                                                                                                                                                             
{                                                                                                                                                                                   
        set_exec_time(0);                                                                                                                                                           
}                                                                                                                                                                                   

void print_exec_timer()                                                                                                                                                             
{                                                                                                                                                                                   
        set_exec_time(1);                                                                                                                                                           
}

Hohe Auflösung ist relativ … Ich habe mir die Beispiele angesehen und sie berücksichtigen meistens Millisekunden. Für mich ist es jedoch wichtig, Mikrosekunden zu messen. Ich habe keine plattformunabhängige Lösung für Mikrosekunden gesehen und dachte, dass so etwas wie der folgende Code nützlich sein wird. Ich habe vorerst nur auf Windows getimt und werde höchstwahrscheinlich eine gettimeofday() -Implementierung hinzufügen, wenn ich dasselbe auf AIX/Linux mache.

    #ifdef WIN32
      #ifndef PERFTIME
        #include <windows.h>
        #include <winbase.h>
        #define PERFTIME_INIT unsigned __int64 freq;  QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq);  unsigned __int64 startTime;  unsigned __int64 endTime;  double timeDifferenceInMilliseconds;
        #define PERFTIME_START QueryPerformanceCounter((LARGE_INTEGER *)&startTime);
        #define PERFTIME_END QueryPerformanceCounter((LARGE_INTEGER *)&endTime); timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);  printf("Timing %fms\n",timeDifferenceInMilliseconds);
    #define PERFTIME(funct) {unsigned __int64 freq;  QueryPerformanceFrequency((LARGE_INTEGER*)&freq);  double timerFrequency = (1.0/freq);  unsigned __int64 startTime;  QueryPerformanceCounter((LARGE_INTEGER *)&startTime);  unsigned __int64 endTime;  funct; QueryPerformanceCounter((LARGE_INTEGER *)&endTime);  double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);  printf("Timing %fms\n",timeDifferenceInMilliseconds);}
      #endif
    #else
      //AIX/Linux gettimeofday() implementation here
    #endif

Verwendungszweck:

PERFTIME(ProcessIntenseFunction());

or

PERFTIME_INIT
PERFTIME_START
ProcessIntenseFunction()
PERFTIME_END

1419340cookie-checkBeste Timing-Methode in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy