3 Stimmen

Benchmark Code - Durch die Anzahl der Iterationen teilen oder nicht?

Ich hatte eine interessante Diskussion mit meinem Freund über das Benchmarking von C/C++-Code (oder Code im Allgemeinen). Wir haben eine einfache Funktion geschrieben, die getrusage verwendet, um die CPU-Zeit für ein bestimmtes Stück Code zu messen. (Es misst, wie viel CPU-Zeit es gebraucht hat, um eine bestimmte Funktion auszuführen). Lassen Sie mich Ihnen ein Beispiel geben:

const int iterationen = 409600; 
double s = measureCPU(); 
for( j = 0; j < iterationen; j++ )
        funktion(args); 
double e = measureCPU(); 
std::cout << (e-s)/iterationen << " s \n";

Wir haben darüber diskutiert, ob wir (e-s) durch die Anzahl der Iterationen teilen sollen oder nicht. Ich meine, wenn wir es nicht teilen, ist das Ergebnis in akzeptabler Form (z. B. 3,0 s), aber wenn wir es teilen, erhalten wir Ergebnisse wie 2,34385e-07 s ...

Also hier sind meine Fragen:

  1. Sollten wir (e-s) durch die Anzahl der Iterationen teilen, wenn ja, warum?
  2. Wie können wir 2,34385e-07 s in einer menschenlesbaren Form ausgeben? (sagen wir, es dauerte 0,00000003 s) ?
  3. Sollen wir zunächst einen Funktionsaufruf einmal durchführen und danach die CPU-Zeit für Iterationen messen, so etwas Ähnliches:

    // Erster Funktionsaufruf, kümmern wir uns überhaupt nicht darum
    funktion(args); 
    // Echtes Benchmarking
    const int iterationen = 409600; 
    double s = measureCPU(); 
    for( j = 0; j < iterationen; j++ )
                funktion(args); 
    double e = measureCPU(); 
    std::cout << (e-s)/iterationen << " s \n";

3voto

nio Punkte 5031
  1. wenn Sie die Zeit durch die Anzahl der Iterationen teilen, erhalten Sie einen Iterationsunabhängigen Vergleich der Laufzeit einer Funktion. Je mehr Iterationen, desto präziser ist das Ergebnis. BEARBEITEN: Es handelt sich um eine durchschnittliche Laufzeit über n Iterationen.

  2. Sie können die geteilte Zeit mit 1e6 multiplizieren, um Mikrosekunden pro Iterationseinheit zu erhalten (ich nehme an, dass measureCPU Sekunden zurückgibt)

    std::cout << 1e6*(e-s)/iterations << " s \n";
  3. wie @ogni42 erwähnt hat, erhalten Sie eine Überlastung von der for-Schleife in Ihre gemessene Zeit, also könnten Sie versuchen, die Schleife ein wenig zu entfalten, um den Messfehler zu verringern, machen Sie 8 bis 16 Aufrufe pro Iteration, versuchen Sie verschiedene Aufrufzahlen, um zu sehen, wie sich die gemessene Zeit ändert:

    for( j = 0; j < iterations; j++ ) {
        function(args);
        function(args);
        function(args);
        function(args);
        ...
    }
  4. Grundsätzlich erhalten Sie eine niedriger ist besser-Zahl. Wenn Sie ein höher ist besser-Ranking wollten, könnten Sie unterschiedliche Variationen der Funktion messen und dann die Zeit der schnellsten ermitteln. Diese könnte 10 Punkte erreichen.

    score_for_actual_function = 10.0 * fastest_time / time_of_actual_function

Dieses Ranking ist irgendwie zeitunabhängig, daher können Sie einfach verschiedene Funktionsvariationen vergleichen und die Funktion kann weniger als einen Punkt erreichen... und achten Sie auf eine Division durch Null :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X