2010-02-28 7 views
42

Gibt es eine einfache Bibliothek, um die Zeit zu messen, die für die Ausführung eines Teils des C-Codes benötigt wird? Was ich will, ist so etwas wie:Wie kann ich C-Code leicht benchmarken?

int main(){ 
    benchmarkBegin(0); 
    //Do work 
    double elapsedMS = benchmarkEnd(0); 

    benchmarkBegin(1) 
    //Do some more work 
    double elapsedMS2 = benchmarkEnd(1); 

    double speedup = benchmarkSpeedup(elapsedMS, elapsedMS2); //Calculates relative speedup 
} 

Es wäre auch schön, wenn die Bibliothek können Sie viele Runs machen, so dass sie im Durchschnitt und die Varianz in Timing Berechnung!

+0

Gute Frage, das mir sehr geholfen. –

+1

Alternativen zu In-Programm-Timing: http://stackoverflow.com/questions/7456146/is-there-a-better-way-to-benchmark-ac-program-than-timing –

+1

Große geschlossene Linux-Frage: http://stackoverflow.com/questions/375913/what-cani-i-use-to-profile-c-code-in-linux –

Antwort

33

Grundsätzlich ist alles, was Sie wollen, ein hochauflösender Timer. Die verstrichene Zeit ist natürlich nur ein Unterschied in den Zeiten und die Beschleunigung wird berechnet, indem die Zeiten für jede Aufgabe geteilt werden. Ich habe den Code für einen Timer mit hoher Auflösung eingefügt, der mindestens auf Windows und Unix funktionieren sollte.

#ifdef WIN32 

#include <windows.h> 
double get_time() 
{ 
    LARGE_INTEGER t, f; 
    QueryPerformanceCounter(&t); 
    QueryPerformanceFrequency(&f); 
    return (double)t.QuadPart/(double)f.QuadPart; 
} 

#else 

#include <sys/time.h> 
#include <sys/resource.h> 

double get_time() 
{ 
    struct timeval t; 
    struct timezone tzp; 
    gettimeofday(&t, &tzp); 
    return t.tv_sec + t.tv_usec*1e-6; 
} 

#endif 
+6

Wallclock time (wie von 'gettimeofday' zurückgegeben) ist möglicherweise nicht so nützlich -' clock_gettime (CLOCK_PROCESS_CPUTIME_ID, ...) 'wird oft dort sein, was dort gesucht wird. – caf

+4

@caf: Ein Programm, das sehr wenig CPU-Zeit verbraucht, aber viel Zeit damit verbringt, E/A zu blockieren oder auf asynchrone E/A zu warten, kann von Benutzern immer noch als langsam empfunden werden. Sowohl die CPU-Zeit als auch die Wanduhrzeit sind wichtig. – bk1e

+7

Ja, deshalb habe ich meinen Kommentar mit den Wieselwörtern "may" und "oft" qualifiziert;) Übrigens, wenn wallclock time * gewünscht ist, dann ist clock_gettime (CLOCK_MONOTONIC, ...) eine bessere Option , denn im Gegensatz zu 'gettimeofday' wird es während des Zeitintervalls nicht von Änderungen der Systemuhr beeinflusst. – caf

1

Versuchen Sie in POSIX getrusage. Das relevante Argument ist RUSAGE_SELF und die relevanten Felder sind ru_utime.tv_sec und ru_utime.tv_usec.

+1

Beachten Sie, dass dies in vielen UNIX-Betriebssystemen, die 'procfs' verwenden, nicht wirklich implementiert ist. (Linux, Solaris) – charliehorse55

0

Möglicherweise gibt es Dienstprogramme, die dabei helfen, aber ich vermute, dass die meisten eine Art von Probenahme oder möglicherweise Injektion verwenden werden. Um bestimmte Abschnitte des Codes zeitgesteuert zu machen, müssen Sie wahrscheinlich Anrufe zu einem Timer hinzufügen, wie Sie ihn in Ihrem Beispiel zeigen. Wenn Sie Windows verwenden, funktioniert der Hochleistungs-Timer. I answered a similar question und zeigte Beispielcode, der das tun wird. Es gibt ähnliche Methoden für Linux.

26

Verwenden Sie die Funktion clock() in time.h definiert:

startTime = (float)clock()/CLOCKS_PER_SEC; 

/* Do work */ 

endTime = (float)clock()/CLOCKS_PER_SEC; 

timeElapsed = endTime - startTime; 
+0

Dies sollte die angenommene Antwort anstelle der Windows-spezifischen sein! – Simon