Ausführungszeit des C-Programms

208

Ich habe ein C-Programm, das auf mehreren Prozessoren parallel 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 der clock()Funktion vorzuschlagen , bei der dann die Anzahl der Uhren berechnet wird, die das Programm geteilt hat, geteilt durch dieClocks_per_second Wert berechnet wird.

Ich bin mir nicht sicher wie Clocks_per_second Wert berechnet wird?

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

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

Ich bin mir auch bewusst, dass ein Profiler eine Option wäre, möchte aber selbst einen Timer implementieren.

Vielen Dank

Roger
quelle
3
Welche OS / API-Frameworks verwenden Sie / sind verfügbar? Einfach nur C?
typo.pl
4
Es ist ein ziemlich kleines Programm, einfach C
Roger
Ich habe in dieser Antwort ausführlich über die Implementierung einer tragbaren Lösung geschrieben: stackoverflow.com/questions/361363/…
Alexander Saprykin
Zeit für die Ausführung einer vollständigen Funktion stackoverflow.com/a/40380118/6180077
Abdullah Farweez

Antworten:

344

CLOCKS_PER_SECist eine Konstante, die in deklariert ist <time.h>. Verwenden Sie Folgendes, um die von einer Aufgabe in einer C-Anwendung verwendete CPU-Zeit abzurufen:

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. messen Sie 4,52 Sekunden). Die Präzision hängt von der Architektur ab. Auf modernen Systemen erreichen Sie leicht 10 ms oder weniger, auf älteren Windows-Computern (aus der Win98-Ära) waren es jedoch eher 60 ms.

clock()ist Standard C; es funktioniert "überall". Es gibt systemspezifische Funktionen wiegetrusage() auf Unix-ähnlichen Systemen.

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

Thomas Pornin
quelle
1
Es gibt mir ein sehr zufälliges Ergebnis - ich bekomme eine Mischung aus großer / kleiner / negativer Zahl über denselben Code. GCC 4.7 Linux 3.2 AMD64
3
Ja: clock()Gibt eine Zeit in einer internen Skala zurück, die als "Uhren" bezeichnet wird, und CLOCKS_PER_SECgibt die Anzahl der Uhren pro Sekunde an. Wenn Sie also durch dividieren, erhalten Sie CLOCKS_PER_SECeine Zeit in Sekunden. Im obigen Code ist der Wert a, doublesodass Sie ihn nach Belieben skalieren können.
Thomas Pornin
18
Große Warnung: clock () gibt die Zeit zurück, die das Betriebssystem für die Ausführung Ihres Prozesses aufgewendet hat, und nicht die tatsächlich verstrichene Zeit. Dies ist jedoch in Ordnung, um einen Codeblock zu steuern, aber nicht um die in der realen Welt verstrichene Zeit zu messen.
2
Er sagte, er wolle ein Multithread-Programm messen. Ich bin mir nicht sicher, ob eine clock () dafür geeignet ist, da sie die Laufzeiten aller Threads zusammenfasst, sodass das Ergebnis so aussieht, als ob der Code nacheinander ausgeführt wurde. Für solche Dinge benutze ich omp_get_wtime (), aber natürlich muss ich sicherstellen, dass das System nicht mit anderen Prozessen beschäftigt ist.
Youda008
1
Ich sollte einige Dinge erwähnen, obwohl dieser Thread vor einem Jahr relevanter war: CLOCKS_PER_SECist ein long intmit dem Wert 1000000, der Zeit in Mikrosekunden angibt, wenn er nicht geteilt wird; keine CPU-Taktzyklen. Daher muss die dynamische Frequenz nicht berücksichtigt werden, da der Takt hier in Mikrosekunden angegeben ist (möglicherweise Taktzyklen für eine 1-MHz-CPU?). Ich habe ein kurzes C-Programm erstellt, das diesen Wert druckt, und es war 1000000 auf meinem i7-2640M-Laptop. mit einer dynamischen Frequenz von 800 MHz bis 2,8 GHz, sogar mit Turbo Boost bis zu 3,5 GHz.
DDPWNAGE
111

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

tun

$ time ./a.out

Wenn Sie a.out als ausführbare Datei annehmen, erhalten Sie die Zeit, die zum Ausführen benötigt wird

S..K
quelle
3
@acgtyrant, aber nur für einfache Programme, da es die gesamte Programmzeit einschließlich Eingabe, Ausgabe usw.
dauern wird
1
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 Ihre Hot-Loop einige Sekunden lang ausführt, können perf stat ./a.outSie HW-Leistungsindikatoren für Cache-Fehler abrufen und Branch Mispredicts und IPC.
Peter Cordes
61

In einfacher Vanille 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;
}
Alexandre C.
quelle
6
Die besten Variablennamen, die ich seit einiger Zeit gesehen habe. tic = "Zeit in Uhr", toc = "Zeit in Uhr". Aber auch tic-toc = "tick-tock". So beschrifte ich von hier an Time Grabs.
Logan Schelly
60

Sie möchten 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 und nicht nur in Sekunden gemessen wird.

Wes Hardaker
quelle
2
Der MinGW-Compiler basiert auf GCC. Also wird es daran funktionieren. Wenn Sie jedoch den Visual C-Compiler verwenden, wird eine Fehlermeldung angezeigt.
user2550754
11
Ja, es funktioniert unter Windows mit einer AC-Bibliothek, die den Aufruf gettimeofday unterstützt. Es spielt eigentlich keine Rolle, was der Compiler ist, Sie müssen ihn nur mit einer anständigen libc-Bibliothek verknüpfen. Was im Fall von mingw nicht das Standardfenster ist.
Wes Hardaker
1
Dies funktioniert für mich unter Windows XP mit cygwin gcc & Linux Ubuntu. Das ist genau das, was ich wollte.
Liebe und Frieden - Joe Codeswell
gettimeofdayist veraltet und wird für neuen Code nicht empfohlen. Die POSIX-Manpage empfiehlt clock_gettime stattdessen , mit der Sie fragen können, CLOCK_MONOTONICob dies nicht durch Änderungen an der Systemuhr beeinflusst wird. ist es besser als Intervallzeit. (Siehe JohnSlls Antwort ). Auf modernen Linux-Systemen ist gettimeofday beispielsweise im Grunde ein Wrapper für clock_gettime, der Nanosekunden in Mikrosekunden konvertiert.
Peter Cordes
12

Die meisten einfachen Programme haben eine Rechenzeit in Millisekunden. Ich nehme an, Sie werden dies 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 folgenden Befehl time austime ./a.out

Adimoh
quelle
In Windows ist mindestens der Faktor mindestens 100, aber nicht 1000 und es ist nicht genau
Boctulus
6
Diese Antwort fügt nichts hinzu, was nicht in Alexandre Cs Antwort von zwei Jahren zuvor enthalten war.
Jonathan Leffler
3
@boctulus: 1s ist immer 1000ms, auch unter Windows.
Alk
9

Viele Antworten wurden vorgeschlagen clock()und dann CLOCKS_PER_SECvon time.h. Dies ist wahrscheinlich eine schlechte Idee, da dies in meiner /bits/time.hDatei steht:

/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

#  if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system.  */
#   include <bits/types.h>
extern long int __sysconf (int);
#   define CLK_TCK ((__clock_t) __sysconf (2))  /* 2 is _SC_CLK_TCK */
#  endif

CLOCKS_PER_SECJe nachdem, welche Optionen Sie zum Kompilieren verwenden, kann dies als 1000000 definiert werden. Daher scheint dies keine gute Lösung zu sein.

Stephen
quelle
1
Danke für die Information, aber gibt es noch eine bessere Alternative?
Ozanmuyes
4
Dies ist kein praktisches Problem: Ja, Posix-Systeme haben immer ein Problem CLOCK_PER_SEC==1000000, aber gleichzeitig verwenden sie alle eine Genauigkeit von 1 µs für ihre clock () -Implementierung. Übrigens hat es die nette Eigenschaft, Probleme beim Teilen zu reduzieren. Wenn Sie potenziell sehr schnelle Ereignisse messen möchten, z. B. unter 1 ms, sollten Sie sich zuerst um die Genauigkeit (oder Auflösung) der clock () -Funktion kümmern, die in Posix notwendigerweise gröber als 1 µs ist, aber häufig auch viel gröber. Die übliche Lösung besteht darin, den Test viele Male auszuführen. Die gestellte Frage schien dies jedoch nicht zu erfordern.
AntoineL
Warum wäre es keine gute Lösung? Sie erhalten einen Wert von clock(), wenn Sie diesen Wert mit Ihnen teilen, erhalten CLOCK_PER_SECSie garantiert Zeit in Sekunden CPU benötigt. Die Verantwortung für die Messung der tatsächlichen Taktrate liegt bei der clock()Funktion, nicht bei Ihnen.
Zaffy
9

Thomas Pornins Antwort 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 so:

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.
hklel
quelle
4

Sie müssen die Zeitmessung berücksichtigen , die ein Programm nahm auszuführen viel von der Last abhängt , dass die Maschine in diesem bestimmten Moment hat.

In dem Wissen, dass der Weg, die aktuelle Zeit in C zu erhalten, auf verschiedene Arten erreicht werden kann, ist ein einfacher:

#include <time.h>

#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + \
  ruse.ru_stime.tv_sec + 1e-6 * \
  (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec))

int main(void) {
    time_t start, end;
    double first, second;

    // Save user and CPU start time
    time(&start);
    first = CPU_TIME;

    // Perform operations
    ...

    // Save end time
    time(&end);
    second = CPU_TIME;

    printf("cpu  : %.2f secs\n", second - first); 
    printf("user : %d secs\n", (int)(end - start));
}

Ich hoffe es hilft.

Grüße!

redent84
quelle
4

(Alle Antworten hier fehlen, wenn Ihr Systemadministrator die Systemzeit ändert oder Ihre Zeitzone unterschiedliche Winter- und Sommerzeiten hat. Daher ...)

Bei Verwendung unter Linux: 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 anders ist als die Sommerzeit 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.
JohnSll
quelle
Können Sie die Berechnung erklären, mit der Sie die Anzahl der Sekunden ermittelt haben? Es ist nicht offensichtlich, was los ist.
Colin Keenan
1
Wäre das nicht (end.tv_nsec - begin.tv_nsec) / 1000000000.0Ergebnis in 0immer?
Alk
@alk: nein, das Teilen durch ein doubleLiteral löst int oder longeine doubleKonvertierung vor der Teilung aus. Natürlich können Sie sich einfach an eine Ganzzahl halten und das tv_secTeil und dann den Bruchteil mit Null drucken %ld.%09ld, aber die Konvertierung in Double ist einfach und 53 Bit Genauigkeit reichen normalerweise für Benchmark-Zeiten aus.
Peter Cordes
1
(Oops, die Subtraktion des ns Teils müssen in die Sekunden Teil tragen, so mit doppelseitigem und läßt sie negativ sein vermeidet dieses Problem. Um einen reinen Integer - Format - String verwenden, würden Sie ein benötigen , timespec_subtractwie die timeval_subtractin dem glibc Handbuch vorgeschlagen : gnu.org/software/libc/manual/html_node/Elapsed-Time.html )
Peter Cordes
3

ANSI C gibt nur Zeitfunktionen mit zweiter Genauigkeit an. Wenn Sie jedoch in einer POSIX-Umgebung ausgeführt werden, können Sie die Funktion gettimeofday () verwenden, die eine Auflösung von Mikrosekunden für die seit der UNIX-Epoche verstrichene Zeit bietet.

Als Randnotiz würde ich die Verwendung von clock () nicht empfehlen, da es auf vielen (wenn nicht allen?) Systemen schlecht implementiert und nicht genau ist, abgesehen von der Tatsache, dass es sich nur darauf bezieht, wie lange Ihr Programm auf der CPU und verbracht hat nicht die Gesamtlebensdauer des Programms, die Sie Ihrer Frage zufolge gerne messen würden.

Shinnok
quelle
Der ISO C-Standard (vorausgesetzt, dies bedeutet ANSI C ) legt absichtlich nicht die Genauigkeit der Zeitfunktionen fest . Speziell bei einer POSIX-Implementierung oder unter Windows ist die Genauigkeit der Wanduhrfunktionen (siehe Antwort von Thomas) in Sekunden angegeben. Aber die Genauigkeit von clock () ist normalerweise größer und in Posix immer 1µs (unabhängig von der Genauigkeit)
AntoineL
2

In meinem System funktionieren nicht alle Lösungen.

Ich kann es gebrauchen

#include <time.h>

double difftime(time_t time1, time_t time0);
Ankit Chilamatur
quelle
2
Dies ergibt die Differenz zwischen zwei time_tWerten als Doppel. Da die time_tWerte nur auf eine Sekunde genau sind, ist sie für den Ausdruck der Zeit, die von Programmen mit kurzer Laufzeit benötigt wird, von begrenztem Wert. Dies kann jedoch für Programme nützlich sein, die über einen längeren Zeitraum ausgeführt werden.
Jonathan Leffler
Aus irgendeinem Grund scheint es für mich mit einer Präzision von einer Hundertstelsekunde zu funktionieren , ein Paar clock_ts an difftimezu übergeben. Dies ist unter Linux x86. Ich kann auch nicht die Subtraktion von stopund startzur Arbeit bekommen.
Ragerdl
@ragerdl: Sie müssen übergeben difftime() clock() / CLOCKS_PER_SEC, da es Sekunden erwartet.
Alk
2
    #include<time.h>
    #include<stdio.h>
    int main(){
clock_t begin=clock();

    int i;
for(i=0;i<100000;i++){
printf("%d",i);

}
clock_t end=clock();
printf("Time taken:%lf",(double)(end-begin)/CLOCKS_PER_SEC);
}

Dieses Programm wird wie Charme funktionieren.

Ravi Kumar Yadav
quelle
2

Ich habe festgestellt, dass die übliche Uhr (), die jeder hier empfiehlt, aus irgendeinem Grund stark von Lauf zu Lauf abweicht, selbst für statischen Code ohne Nebenwirkungen, wie Zeichnen auf dem Bildschirm oder Lesen von Dateien. Dies kann daran liegen, dass die CPU den Stromverbrauch ändert, das Betriebssystem unterschiedliche Prioritäten setzt usw.

Die einzige Möglichkeit, mit clock () jedes Mal zuverlässig das gleiche Ergebnis zu erzielen, besteht darin, den gemessenen Code mehrmals (mehrere Minuten lang) in einer Schleife auszuführen und dabei Vorsichtsmaßnahmen zu treffen, um zu verhindern, dass der Compiler ihn optimiert: Moderne Compiler können den Code vorberechnen ohne Nebenwirkungen, die in einer Schleife ausgeführt werden, und verschieben Sie sie aus der Schleife heraus, z. B. indem Sie für jede Iteration eine zufällige Eingabe verwenden.

Nachdem genügend Samples in einem Array gesammelt wurden, sortiert man dieses Array und nimmt das mittlere Element, den Median. Der Median ist besser als der Durchschnitt, da er extreme Abweichungen beseitigt, z. B. wenn Antivirenprogramme die gesamte CPU belegen oder das Betriebssystem Aktualisierungen vornimmt.

Hier ist ein einfaches Dienstprogramm zum Messen der Ausführungsleistung von C / C ++ - Code, bei dem die Werte nahe dem Median gemittelt werden: https://github.com/saniv/gauge

Ich selbst bin immer noch auf der Suche nach einer robusteren und schnelleren Methode zum Messen von Code. Man könnte wahrscheinlich versuchen, den Code unter kontrollierten Bedingungen auf Bare-Metal ohne Betriebssystem auszuführen, aber das führt zu einem unrealistischen Ergebnis, da in Wirklichkeit das Betriebssystem involviert ist.

x86 verfügt über diese Hardwareleistungsindikatoren, die die tatsächliche Anzahl der ausgeführten Anweisungen enthalten. Sie sind jedoch ohne Hilfe des Betriebssystems schwierig zuzugreifen, schwer zu interpretieren und haben ihre eigenen Probleme ( http://archive.gamedev.net/archive/reference/articles) /article213.html ). Dennoch könnten sie hilfreich sein, um die Art des Flaschenhalses zu untersuchen (Datenzugriff oder tatsächliche Berechnungen dieser Daten).

SmugLispWeenie
quelle
Ja, moderne x86-CPUs laufen viel langsamer im Leerlauf als Max Turbo. Abhängig von den "Regler" -Einstellungen kann das Hochfahren auf die maximale Taktrate eine Millisekunde (Skylake mit Hardware-P-Status-Management, insbesondere bei aktivierter Energie-Leistungspräferenz performance) oder viele zehn Millisekunden dauern . en.wikipedia.org/wiki/Dynamic_frequency_scaling . Und ja, die mittlere Leistung ist normalerweise eine gute Wahl. Das High-End weist normalerweise einige Störspitzen auf.
Peter Cordes
Oft ist es am besten, eine Befehlszeileneingabe zu verwenden und das Ergebnis zurückzugeben, um zu vermeiden, dass die Arbeit wegoptimiert wird. Oder schreiben Sie eine Funktion in eine separate Datei main, die ein Argument annimmt und ein Ergebnis zurückgibt, und verwenden Sie keine Optimierung der Verbindungszeit. Dann kann der Compiler es nicht in den Aufrufer einbinden. Funktioniert nur, wenn die Funktion bereits eine Art Schleife enthält, andernfalls ist der Overhead für Aufruf / Ret zu hoch.
Peter Cordes
Der Compiler kann die einzelne Befehlszeileneingabe aus der Schleife heraus weiterhin optimieren, wenn Sie sie mit statischem Code ohne Nebenwirkungen verarbeiten. Daher ist es am besten, für jede Iteration eine zufällige Eingabe zu generieren. Offensichtlich sollte rand () vor dem ersten Takt () außerhalb des gemessenen Codes aufgerufen werden, da rand () auch zu einem Systemaufruf führen kann, bei dem ein Hardware-Entropie-Generator (der auf älteren Systemen eine Mausbewegung war) abgetastet wird. Vergessen Sie nur nicht, jedes Bit der Ausgabe auszudrucken, da der Compiler sonst möglicherweise entscheidet, dass Sie nicht die gesamte Ausgabe als Ganzes oder als Teil davon benötigen. Dies kann beispielsweise mit CRC32 erfolgen.
SmugLispWeenie
Wenn Ihr zu testender Code in einer separaten Datei gespeichert ist und Sie keine Optimierung der Verbindungszeit verwenden, kann der Compiler CSE nicht ausführen, um zwischen Aufrufen zu optimieren. Der Anrufer kann nicht davon ausgehen, dass der Angerufene keine sichtbaren Nebenwirkungen hat. Auf diese Weise können Sie etwas relativ Kurzes in eine Wiederholungsschleife einfügen, um die Zeit zu verlängern. Wenn Sie es inline lassen, müssen Sie den generierten asm überprüfen, um sicherzustellen, dass keine Berechnung aus einer Schleife gezogen wurde, wie Sie sagen.
Peter Cordes
Die compilerspezifische Methode besteht darin, (zum Beispiel) GNU C inline asm zu verwenden, um einen Compiler zu zwingen, ein Ergebnis in einem Register zu materialisieren und / oder zu vergessen, was er über den Wert einer Variablen weiß, ohne tatsächlich zusätzliche Anweisungen einzuführen. "Escape" - und "Clobber" -Äquivalent in MSVC- Links zu einem Video über Profiling und Microbenchmarking (Clang-Entwickler Chandler Carruths CppCon 2015-Vortrag) Es gibt kein MSVC-Äquivalent, aber die Frage selbst zeigt die GNU C-Funktionen und deren Verwendung.
Peter Cordes
0

Man könnte eine andere Art von Eingabe nützlich finden: Ich habe diese Methode gegebener Zeit im Rahmen eines Hochschulstudium auf GPGPU-Programmierung mit CUDA (Messkursbeschreibung ). Es kombiniert Methoden, die in früheren Beiträgen verwendet wurden, und ich poste sie einfach, weil die Anforderungen ihr Glaubwürdigkeit verleihen:

unsigned long int elapsed;
struct timeval t_start, t_end, t_diff;
gettimeofday(&t_start, NULL);

// perform computations ...

gettimeofday(&t_end, NULL);
timeval_subtract(&t_diff, &t_end, &t_start);
elapsed = (t_diff.tv_sec*1e6 + t_diff.tv_usec);
printf("GPU version runs in: %lu microsecs\n", elapsed);

Ich nehme an, Sie könnten mit zB multiplizieren 1.0 / 1000.0, um die Maßeinheit zu erhalten, die Ihren Anforderungen entspricht.

ワ イ き ん ぐ
quelle
1
gettimeofday ist veraltet und wird nicht empfohlen. Die POSIX-Manpage empfiehlt clock_gettimestattdessen, dass Sie fragen können, CLOCK_MONOTONICob dies nicht durch Änderungen an der Systemuhr beeinflusst wird, und daher besser als Intervall-Timer geeignet ist. Auf modernen Linux-Systemen ist beispielsweise gettimeofdayein Wrapper clock_gettime, der Nanosekunden in Mikrosekunden umwandelt. (Siehe JohnSlls Antwort).
Peter Cordes
Diese Methode wurde von @Wes Hardaker hinzugefügt, der Hauptunterschied ist die Verwendung timeval_subtract.
ぐ イ き. ぐ
Ok, der einzig nützliche Teil Ihrer Antwort ist der Name einer Funktion, die Sie nicht definieren und die nicht in der Standardbibliothek enthalten ist. (Nur im glibc-Handbuch: gnu.org/software/libc/manual/html_node/Elapsed-Time.html ).
Peter Cordes
-2

Vergleich der Ausführungszeit von Blasensortierung und Auswahlsortierung Ich habe ein Programm, das die Ausführungszeit von Blasensortierung und Auswahlsortierung vergleicht. Um den Zeitpunkt der Ausführung eines Codeblocks herauszufinden, berechnen Sie die Zeit vor und nach dem Block durch

 clock_t start=clock();
 
 clock_t end=clock();
 CLOCKS_PER_SEC is constant in time.h library

Beispielcode:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   int a[10000],i,j,min,temp;
   for(i=0;i<10000;i++)
   {
      a[i]=rand()%10000;
   }
   //The bubble Sort
   clock_t start,end;
   start=clock();
   for(i=0;i<10000;i++)
   {
     for(j=i+1;j<10000;j++)
     {
       if(a[i]>a[j])
       {
         int temp=a[i];
         a[i]=a[j];
         a[j]=temp;
       }
     }
   }
   end=clock();
   double extime=(double) (end-start)/CLOCKS_PER_SEC;
   printf("\n\tExecution time for the bubble sort is %f seconds\n ",extime);

   for(i=0;i<10000;i++)
   {
     a[i]=rand()%10000;
   }
   clock_t start1,end1;
   start1=clock();
   // The Selection Sort
   for(i=0;i<10000;i++)
   {
     min=i;
     for(j=i+1;j<10000;j++)
     {
       if(a[min]>a[j])
       {
         min=j;
       }
     }
     temp=a[min];
     a[min]=a[i];
     a[i]=temp;
   }
   end1=clock();
   double extime1=(double) (end1-start1)/CLOCKS_PER_SEC;
   printf("\n");
   printf("\tExecution time for the selection sort is %f seconds\n\n", extime1);
   if(extime1<extime)
     printf("\tSelection sort is faster than Bubble sort by %f seconds\n\n", extime - extime1);
   else if(extime1>extime)
     printf("\tBubble sort is faster than Selection sort by %f seconds\n\n", extime1 - extime);
   else
     printf("\tBoth algorithms have the same execution time\n\n");
}
JAGDISCHES DUDHAT
quelle
4
Dies fügt nicht wirklich etwas Neues im Vergleich zu adimoh ‚s Antwort , mit der Ausnahme , dass es in füllt‚den ausführbaren Code‘Block (oder zwei) mit einigem eigentlichen Code. Und diese Antwort fügt nichts hinzu, was nicht in Alexandre Cs Antwort von vor zwei Jahren enthalten war.
Jonathan Leffler