C/C++ Forum :: Linux/Unix :: Millisekunden messen



  • 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;
    

Anmelden zum Antworten