Ausführungszeit des C-Programms

Lesezeit: 8 Minuten

Rogers Benutzeravatar
Roger

Ich habe ein C-Programm, das parallel auf mehreren Prozessoren ausgeführt werden soll. Ich muss in der Lage sein, die Ausführungszeit aufzuzeichnen (die zwischen 1 Sekunde und mehreren Minuten liegen kann). Ich habe nach Antworten gesucht, aber alle scheinen die Verwendung von vorzuschlagen clock() Funktion, die dann die Berechnung der Anzahl der Takte, die das Programm benötigt hat, dividiert durch die beinhaltet Clocks_per_second Wert.

Ich bin mir nicht sicher, wie die Clocks_per_second Wert berechnet?

In Java nehme ich einfach die aktuelle Zeit in Millisekunden vor und nach der Ausführung.

Gibt es etwas ähnliches in C? Ich habe es mir angesehen, aber ich kann anscheinend keinen Weg finden, etwas Besseres als eine zweite Auflösung zu bekommen.

Mir ist auch bewusst, dass ein Profiler eine Option wäre, aber ich möchte selbst einen Timer implementieren.

Vielen Dank

  • Welche OS/API-Frameworks verwenden Sie/sind verfügbar? Einfach nur C?

    – typo.pl

    9. März 2011 um 16:37 Uhr

  • Es ist ein ziemlich kleines Programm, einfach nur C

    – Roger

    9. März 2011 um 16:39 Uhr

  • Ich habe in dieser Antwort ausführlich über die Implementierung einer portablen Lösung geschrieben: stackoverflow.com/questions/361363/…

    – Alexander Saprikin

    27. Juni 2016 um 13:53 Uhr

  • Zeitaufwand für die Ausführung einer vollständigen Funktion stackoverflow.com/a/40380118/6180077

    – Abdullah Farweez

    17. Mai 2017 um 5:05 Uhr

  • Entschuldigung, die Stimmen waren “256” * (perfekte Zahl.. 😂️) und hier komme ich, um es auf 257 hochzustimmen. en.wikipedia.org/wiki/256_(number)#In_computing

    – Wilhelm Martens

    17. Juli um 20:44 Uhr


Benutzeravatar von Thomas Pornin
Thomas Pornin

CLOCKS_PER_SEC ist eine Konstante, die in deklariert ist <time.h>. Um die CPU-Zeit zu erhalten, die von einer Aufgabe innerhalb einer C-Anwendung verwendet wird, verwenden Sie:

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

Beachten Sie, dass dies die Zeit als Gleitkommatyp zurückgibt. Dies kann genauer als eine Sekunde sein (z. B. Sie messen 4,52 Sekunden). Die Genauigkeit hängt von der Architektur ab; Auf modernen Systemen erreichen Sie leicht 10 ms oder weniger, aber auf älteren Windows-Computern (aus der Win98-Ära) waren es eher 60 ms.

clock() ist Standard-C; es funktioniert “überall”. Es gibt systemspezifische Funktionen, wie z getrusage() auf Unix-ähnlichen Systemen.

Javas System.currentTimeMillis() misst nicht dasselbe. Es ist eine “Wanduhr”: Sie kann Ihnen helfen zu messen, wie viel Zeit für die Ausführung des Programms benötigt wurde, aber es sagt Ihnen nicht, wie viel CPU-Zeit verwendet wurde. Auf Multitasking-Systemen (dh allen) können diese sehr unterschiedlich sein.

  • Es gibt mir ein sehr zufälliges Ergebnis – ich bekomme eine Mischung aus großen/kleinen/negativen Zahlen über denselben Codeabschnitt. GCC 4.7 Linux 3.2 AMD64

    Benutzer972946

    2. Juni 2013 um 1:40 Uhr


  • das gibt die zeit in sekunden an?

    – cristi.gherghina

    7. November 2015 um 9:48 Uhr

  • Ja: clock() gibt eine Zeit in einer internen Skala namens “Uhren” zurück, und CLOCKS_PER_SEC ist die Anzahl der Takte pro Sekunde, also geteilt durch CLOCKS_PER_SEC ergibt eine Zeit in Sekunden. Im obigen Code ist der Wert a double sodass Sie es beliebig skalieren können.

    – Thomas Pornin

    7. November 2015 um 16:56 Uhr

  • Große Warnung: clock() gibt die Zeit zurück, die das Betriebssystem mit der Ausführung Ihres Prozesses verbracht hat, und nicht die tatsächlich verstrichene Zeit. Dies ist jedoch in Ordnung, um einen Codeblock zu timen, aber nicht um die Zeit zu messen, die in der realen Welt vergeht.

    Benutzer3703887

    28. März 2016 um 18:31 Uhr

  • Er sagte, er wolle ein Multithread-Programm messen. Ich bin mir nicht sicher, ob ein clock() dafür geeignet ist, da es die Laufzeiten aller Threads summiert, sodass das Ergebnis so aussieht, als ob der Code sequentiell ausgeführt würde. Für solche Dinge verwende ich omp_get_wtime(), aber natürlich muss ich sicherstellen, dass das System nicht mit anderen Prozessen beschäftigt ist.

    – Youda008

    15. Oktober 2016 um 8:12 Uhr

Wenn Sie die Unix-Shell zum Ausführen verwenden, können Sie den Befehl time verwenden.

tun

$ time ./a.out

Unter der Annahme von a.out als ausführbare Datei erhalten Sie die Zeit, die zum Ausführen dieser Datei benötigt wird

  • @acgtyrant, aber nur für einfache Programme, da es die gesamte Programmzeit in Anspruch nimmt, einschließlich Eingabe, Ausgabe usw.

    – phuklv

    17. Dezember 2015 um 6:55 Uhr

  • Wenn Sie unter Linux arbeiten und Ihren (Mikro-)Benchmark auf ein Programm mit vernachlässigbarem Startaufwand reduziert haben, z. B. eine statische ausführbare Datei, die Ihren Hot Loop für einige Sekunden ausführt, können Sie verwenden perf stat ./a.out um HW-Leistungsindikatoren für Cache-Fehlschläge und Verzweigungs-Fehlvorhersagen und IPC zu erhalten.

    – Peter Cordes

    5. April 2019 um 8:12 Uhr

  • Siehe auch Idiomatische Art der Leistungsbewertung? Weitere Informationen zu den Fallstricken des Microbenchmarking finden Sie z. Und Sie müssen die Optimierung aktivieren, aber nicht Ihre eigentliche Arbeit wegoptimieren oder Teile davon aus Ihrer Wiederholungsschleife heben/senken lassen.

    – Peter Cordes

    19. August um 11:42 Uhr

Benutzeravatar von Alexandre C
Alexandre C.

In Plain Vanilla C:

#include <time.h>
#include <stdio.h>

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}

  • Die besten Variablennamen, die ich seit langem gesehen habe. tic = “Zeit in Uhr”, toc = “Zeit aus Uhr”. Aber auch tic-toc = „tick-tack“. So bezeichne ich von nun an Zeitraffer.

    – Logan Schelly

    30. März 2020 um 2:57 Uhr

  • Beachten Sie, dass tic und toc sind die Namen der Standard-Stoppuhr-Timer-Funktionen in MATLAB, die identisch verwendet werden. Daher bin ich mir nicht sicher, ob man der Originalität Ehre machen muss, aber das erhöht umso mehr ihre Wahrscheinlichkeit, erkannt und verstanden zu werden.

    – Cody Grey

    3. März um 8:37


  • @CodyGray Oh, das wusste ich nicht. Ich habe diese Variablennamen irgendwo gesehen, vor mehr als 10 Jahren oder so scheint es 🙂 Ich benutze sie immer noch tic und toc im Jahr 2022, also kann ich das nächste Mal, wenn ich Kollegen in Code-Reviews zum Zwinkern bringe, erklären, woher das kommt 🙂

    – Alexander C.

    3. März um 14:38 Uhr

  • @ Leos313: Als ich unter einer anderen Antwort auf ein Duplikat dieses Kommentars geantwortet habe: the clock() Die Funktion steht in keinem Zusammenhang mit den Kerntaktzyklen moderner Systeme. dies ist notwendig, damit dieselben Binärdateien auf anderen Systemen funktionieren; Sie müssen alle mit der gleichen CLOCKS_PER_SEC kompiliert werden, um mit der libc übereinzustimmen clock() Retouren auf verschiedenen Maschinen.

    – Peter Cordes

    19. August um 11:40 Uhr

  • @ Leos313: Du meinst so wie dieses bestehende? Wie ist die Beziehung zwischen der tatsächlichen CPU-Frequenz und der clock_t in C?

    – Peter Cordes

    19. August um 19:36 Uhr

Benutzeravatar von Wes Hardaker
Wes Hardaker

Sie wollen dies funktional:

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

Beachten Sie, dass dies in Mikrosekunden gemessen wird, nicht nur in Sekunden.

Benutzeravatar von adimoh
adimoh

Die meisten einfachen Programme haben eine Rechenzeit in Millisekunden. Also, ich nehme an, Sie werden das nützlich finden.

#include <time.h>
#include <stdio.h>

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

Wenn Sie die Laufzeit des gesamten Programms berechnen möchten und sich auf einem Unix-System befinden, führen Sie Ihr Programm mit dem aus Zeit Befehl so time ./a.out

  • Unter Windows ist der Faktor mindestens 100, aber nicht 1000 und nicht exakt

    – Boctulus

    16. April 2016 um 12:29 Uhr

  • Diese Antwort fügt nichts hinzu, was nicht in Alexandre Cs Antwort von zwei Jahren zuvor enthalten war.

    – Jonathan Leffler

    5. Dezember 2016 um 1:25 Uhr

  • @boctulus: 1s ist stets 1000ms, auch unter Windows.

    – alk

    21. Juli 2017 um 15:09 Uhr

Benutzeravatar von JohnSll
JohnSll

(Hier fehlen alle Antworten, wenn Ihr Systemadministrator die Systemzeit ändert, oder Ihre Zeitzone unterschiedliche Winter- und Sommerzeiten hat. Deshalb…)

Bei Linux-Nutzung: clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable);
Es ist nicht betroffen, wenn der Systemadministrator die Zeit ändert oder Sie in einem Land leben, in dem die Winterzeit von der Sommerzeit abweicht usw.

#include <stdio.h>
#include <time.h>

#include <unistd.h> /* for sleep() */

int main() {
    struct timespec begin, end;
    clock_gettime(CLOCK_MONOTONIC_RAW, &begin);

    sleep(1);      // waste some time

    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    printf ("Total time = %f seconds\n",
            (end.tv_nsec - begin.tv_nsec) / 1000000000.0 +
            (end.tv_sec  - begin.tv_sec));

}

man clock_gettime Zustände:

CLOCK_MONOTONIC
              Clock  that  cannot  be set and represents monotonic time since some unspecified starting point.  This clock is not affected by discontinuous jumps in the system time
              (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.

  • Unter Windows ist der Faktor mindestens 100, aber nicht 1000 und nicht exakt

    – Boctulus

    16. April 2016 um 12:29 Uhr

  • Diese Antwort fügt nichts hinzu, was nicht in Alexandre Cs Antwort von zwei Jahren zuvor enthalten war.

    – Jonathan Leffler

    5. Dezember 2016 um 1:25 Uhr

  • @boctulus: 1s ist stets 1000ms, auch unter Windows.

    – alk

    21. Juli 2017 um 15:09 Uhr

Benutzeravatar von hklel
hklel

Antwort von Thomas Pornin als Makros:

#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

Verwenden Sie es wie folgt:

TICK(TIME_A);
functionA();
TOCK(TIME_A);

TICK(TIME_B);
functionB();
TOCK(TIME_B);

Ausgabe:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.

1426420cookie-checkAusführungszeit des C-Programms

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

Privacy policy