L
FAQ - Eintrag
gettimeofday ist zum Messen der Zeit ungeeignet, da es durch Verstellen an der Uhr (seis nun händisch oder automatisch durch ntp&co) aus dem Takt kommt.
Wie auch schon hier angesprochen, ist für Zeitmessungen clock_gettime besser geeignet.
Damit lässt sich die Zeit messen, aber auch die Zeit wie viel Rechenzeit der Prozess/Thread bekommen hat.
Erklärung der Verschiedenen "clocks":
CLOCK_REALTIME : Ist die normale Systemuhr. Also Sekunden seit 1970 und kann halt verstellt werden.
CLOCK_MONOTONIC : Tickt seit dem Booten (an sich egal seit wann) unaufhörlich und unveränderlich.
CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID : Tickt nur wenn der Prozess/Thread gerade läuft. Also zB würde ein sleep(1); hier praktisch ignoriert werden. Manchmal ganz praktisch, aber evtl spielen ja andere Prozesse/Threads auch eine Rolle.
Also in C:
#include <stdio.h>
#include <time.h>
/*
* gcc -lrt ...
*/
int main()
{
struct timespec ts_res, ts_start, ts_end;
clock_getres(CLOCK_MONOTONIC, &ts_res);
printf("Resolution: %lus and %lins\n", ts_res.tv_sec, ts_res.tv_nsec);
clock_gettime(CLOCK_MONOTONIC, &ts_start);
/* mach was */
clock_gettime(CLOCK_MONOTONIC, &ts_end);
printf("Elapsed time: %luns\n", (ts_end.tv_sec - ts_start.tv_sec) * 1000000000 + ts_end.tv_nsec - ts_start.tv_nsec);
return 0;
}
Und in einer kleinen Klasse für C++:
#include <ctime>
#include <string>
class timer
{
struct timespec ts_start, ts_end;
clockid_t id;
public:
void start() {
clock_gettime(id, &ts_start);
}
void stop() {
clock_gettime(id, &ts_end);
}
timer(clockid_t clock = CLOCK_MONOTONIC) {
id = clock;
start();
}
friend std::ostream & operator<<(std::ostream& os, const timer &t);
};
std::ostream & operator<<(std::ostream& os, const timer &t)
{
unsigned long ns = (t.ts_end.tv_sec - t.ts_start.tv_sec) * 1000000000 + t.ts_end.tv_nsec - t.ts_start.tv_nsec;
string ext = "ns";
if (ns >= 10000) {
ns /= 1000;
ext = "us";
}
if (ns >= 10000) {
ns /= 1000;
ext = "ms";
}
if (ns >= 10000) {
ns /= 1000;
ext = "s";
}
os << ns << " " << ext;
return os;
}
Benutzen dann mit
timer t;
//optional: t.start()
//wird schon im Konstruktor aufgerufen,
//aber für wiederverwendung etc
//Tu was, was gemessen werden soll
t.stop();
cout << "Etwas hat " << t << " gedauert!" << endl;