GetTickCount für Linux?



  • hä inwievern ?



  • Er meint da gettimeofday einen Zeitpunktabhängigen Stempel liefert, kannst Du Messungen manipulieren, indem Du den Startzeitpunkt festhälst, die Uhr 10 Minuten zurück drehst und dann die Stoppzeit festhälst. Das Programm wäre jetzt -10 Minuten gelaufen...

    Mit einem Clockstempel (Anzahl irgendeines Taktes seit Systemstart) kann man das nicht.



  • Gerade scharmlos geklaut und nicht getestet, aber vielleicht hilfreich

    #include <sys/sysinfo.h>
    long getTickCount() // Zeit seit dem Booten in Sekunden
    {
     struct sysinfo si;
     if(sysinfo(&si) == 0) return si.uptime;
    
     return -1;
    }
    

    btw. war der 2. Treffer bei google 🤡



  • long uptime; /* Seconds since boot */



  • Ich wollte nur anmerken, dass ich noch keine Lösung gefunden habe 😃



  • eventuell mit dem rdtsc CPU-Befehl?



  • denke seit cool & quiet und aehnliches ist ein umrechen auf zeit mit rdtsc eher schwierig



  • ... und ich fand: man: clock_gettime 🙂



  • Das war ja ne schwere Geburt 😃

    Nee im Ernst, kannte ich auch noch nicht und werde mir vornehmen, es nicht wieder zu vergessen, falls ich das auch mal brauche (oder mal jemand fragt :D), zumal das nichts exotisches sondern POSIX Standard ist.



  • LordJaxom schrieb:

    zumal das nichts exotisches sondern POSIX Standard ist.

    Mac OS X/Darwin haben es trotzdem nicht 👎 😞 😡



  • Jetzt habe ich ein weiteres Problem gehabt: sowohl usleep als auch nanosleep schlafen länger, als sie sollen. IdR brauchen beide Funktionen 2ms zu lange. Ich habe nun umständlich ein eigene Schlaf-Funktion gemacht, welcher einen Teil der Zeit mit nanosleep abdeckt und den Rest in einer Endlodschleife abwartet, was eine hohe CPU-Zeit und 0-2% Auslastung durch die Schleife zur Folge hat. Dafür habe ich in 95% der Aufrufe eine Abweichung von 1µs.



  • 2ms können gut vom Scheduling kommen. Wenn du sleep benutzt, sagt das Programm dem Scheduler ja "Wecke mich in x ms" und wenn gerade kein Zeitfenster zur Verfügung steht, dann dauert es, bis dein Prozess geweckt wird.

    Wenn du aber eine Endlosschleife hast, dann bekommt dein Programm ja ständig Rechenzeit.

    Vielleicht hilft es ja die Priorität des Prozesses anzuheben (man: setpriority(2)). An sonsten benötigst du wohl Realtimeerweiterungen



  • Priorität habe ich schon von 0 auf 10 erhöht (die Linux-Prioritäten sagen mir nicht wirklich viel ;))
    Was ist eine Realtime-Erweiterung? Die Sleep-Funktion ist übrigens für einen Gameserver.



  • Wenn Du mit Priorität nice-Werte meinst, da sind die niedrigeren höher, will heissen -19 ist die höchste Priorität 😉



  • Wieso hat Teamspeak dann einen Wert von 19? 😮

    *edit* Kann es sein, dass nur der root einen Nice-Wert < 0 setzen darf?



  • Ist richtig, negative (also hohe) Prios sind root vorbehalten.



  • LordJaxom schrieb:

    Hallo,

    Die Funktion gettimeofday liefert Dir Mikrosekunden ganz ohne Überlauf 😉

    Ich benutze immer folgende Funktion wenn ich Zeitmessungen machen will (ohne mit den zwei Membern der timeval struct hantieren zu müssen):

    uint64_t getTimeMs(void)
    {
        struct timeval tv;
    
        gettimeofday(&tv, 0);
        return uint64_t( tv.tv_sec ) * 1000 + tv.tv_usec / 1000;
    }
    

    Seit wann Microsekunden? Sollten das nicht Millisekunden sein? Microsekunden seit 1970 ist selbst für nen unsigned long zuviel.



  • Neku schrieb:

    ... und ich fand: man: clock_gettime 🙂

    Hallo,

    versuche das gerade unter FreeBSD anzuwenden, aber irgendwie will's nicht so recht... Jemand ne Idee wo der Fehler liegt?

    #ifndef CLOCK_MONOTONIC
     #define CLOCK_MONOTONIC _SC_MONOTONIC_CLOCK
    #endif
    
    //# define GET_TIME(x) x = GetTickCount()
    # define GET_TIME(x) { struct timespec abc; \
    clock_gettime(CLOCK_MONOTONIC, &abc); \
    printf("++++++++sec: %ld usec: %ld\n", abc.tv_sec, abc.tv_nsec); \
    x = (int)(abc.tv_sec * 1000 + abc.tv_nsec * 0.000001); }
    

    Der fprint ist natürlich nur zum Test drin und zeigt beim ersten Aufruf von GET_TIME(x) "sec: 671415874 usec: 0" und danach immer für beide 0... Könnte natürlich gut sein, dass meine Definition von CLOCK_MONOTONIC falsch ist, gcc meinte sie wär undeclared und den Schnipsel von ganz oben habe ich dann beim googlen gefunden.
    CLOCK_MONOTONIC hat dann den Wert 74...



  • Bei meiner bits/time.h ist CLOCK_MONOTONIC als 1 definiert.

    Unter Linux sieht das bei mir so aus:

    uint32 timeGetTime()
    {
    	timespec tp;
    	::clock_gettime (CLOCK_MONOTONIC, &tp);
    
    	return (tp.tv_sec * 1000 + tp.tv_nsec / 1000000);
    }
    

    LordJaxom schrieb:

    Ist richtig, negative (also hohe) Prios sind root vorbehalten.

    Ich weiß nicht wieso, aber bei meinem Linux ist das plötzlich anders und mein Prozess läuft als normaler User mit einem Nice-Wert von -10.

    Ich suche im übrigen noch immer ein präziseres Äquivalent zu Sleep von Windows. sleep, usleep und nanosleep schlafen alle länger als sie sollen und das passt mir nicht 😉

    Vorübergehende, CPU-fressende Lösung:

    void Sleep
    	(uint32 uMilliseconds)
    {
    	if (!uMilliseconds)
    		return;
    
    	timespec tp;
    
    	::clock_gettime (CLOCK_MONOTONIC, &tp);
    	uint32 uStart = tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
    
    	uint32 uMicroseconds = uMilliseconds * 1000;
    	tp.tv_sec = 0;
    
    	if (uMicroseconds > 1000)
    	{
    		tp.tv_nsec = uMicroseconds * 1000 - 1500000;
    		::nanosleep (&tp, 0);
    	}
    
    	do
    	{
    		::clock_gettime (CLOCK_MONOTONIC, &tp);
    	}
    	while (tp.tv_sec * 1000000 + tp.tv_nsec / 1000 - uStart < uMicroseconds);
    }
    

    Passt idR auf die Millisekunde genau bei einer CPU-Auslastung von ca. 4%.



  • Diese Diskussion hat mir sehr geholfen, ich war auf der Suche nach einem Ersatz für GetTickCount auf Solaris.

    Leider verwenden wir ein etwas ältliches Solaris und daher war clock_gettime keine Alternative (kennt weder CLOCK_MONOTONIC noch CLOCK_UPTIME).

    Aber irgendwie bin ich über clock_gettime auf gethrtime gestossen. Das gibt es auch in RTLinux.

    Und falls Neku es noch lesen sollte:
    Es würde mich interessieren, was Neku sicher macht, dass die sleeps auf WIN exakter funktionieren.
    Wenn es mit GetTickCount gemessen wurde, ist es kein Wunder dass WIN exakter erscheint. GetTickCount liefert zwar eine Zeit in Millisekunden, wird aber üblicherweise nur alle 10-16ms um 10-16 erhöht. Also die 2ms, die Linux laut Neku "idR" zu lange braucht, gehen auf WIN in der Messgenauigkeit unter (so mit GetTickCount gemessen wurde).


Anmelden zum Antworten