Hohe CPU-Last wegen clock_gettime



  • stoppuhr schrieb:

    Ich bin weiterhin daran interessiert an einem Time Aufruf der wenig Zeit kostet, aber warum funktioniert das bei mir nicht? An was könnte es scheitern?

    Schon die 300ns ist eine so unvorstellbar kurze Zeit. Und gerade auch noch im Vergleich zu I/O. Dann kann 300ns wirklich nicht ins Gewicht fallen. Von daher kann keine "Hohe CPU-Lasdt wegen clock_gettime" entstehen. Du machst etwas grundlegend falsch.

    Und den Test habe ich mir angeschaut. Der Testet die Geschwindigkeit einer Zählschleife und eine Zeitermittlung. Aber sobald ich irgendetwas in der Schleife mache, dann verschwinden die Unterschiede zwischen den Zeitmessmethoden im Bereich der Messungenauigkeit.



  • SeppJ schrieb:

    Könntest du diesen Punkt etwas erläutern? Wir wissen schon, dass du meinst, du musst die Zeiten pro Element messen. Aber wenn du uns sagst, warum das so sein sollte, dann fällt uns vielleicht/wahrscheinlich eine viel bessere Lösung ein. Ich habe nämlich gerade irgendwie den Verdacht, dass du Schedulingfunktionen des OS nachprogrammierst.

    hmm weiß jetzt nicht wie ich es anders erklären soll als wie ich es schon gemacht habe.
    Zwischenzeit wird für Abbruchkriterium verwendet, falls das Eintritt, dann wird das das Element nicht mehr fertig abgearbeitet. Wird u.a. verwendet damit das Element nicht zu lange gelockt wird und falls es zu lange dauert gibt es Zustände wo es einfach keinen Sinn macht noch weiter zu machen.
    Endzeit brauche ich, damit man im nachhinein sieht ob ein Element ständig zu lange braucht für die Abarbeitung oder im Vergleich zum Durchschnitt usw.

    [quote="tntnetSchon die 300ns ist eine so unvorstellbar kurze Zeit. Und gerade auch noch im Vergleich zu I/O. Dann kann 300ns wirklich nicht ins Gewicht fallen. Von daher kann keine "Hohe CPU-Lasdt wegen clock_gettime" entstehen. Du machst etwas grundlegend falsch.[/quote]
    Ja nur was mache ich dann grundlegend falsch? 😉
    Mein Thread hat mit der time-Funktion im ca. 37% CPU-Core Auslastung und ohne dem Aufruf 23%
    Somit wäre es für mich denkbar, wenn CLOCK_MONOTONIC_COARSE bei mir so funktionieren würde wie in div. Tests , dass ich dann auf 28% komme würde.
    Ja ich weiß, was wäre wenn .... 😞



  • stoppuhr schrieb:

    gibt es eine Art Stoppuhr die weniger CPU benötigt?

    Zumindest für die x86-32/64 Architekturen würde sich inline Assembler als Alternative anbieten: es gibt den Befehl RDTSC (read time stamp counter), der den aktuellen Wert eines 64Bit Zählers ausliest, der mit jede Taktzyklus der CPU inkrementiert wird. Wenn man die maximale CPU Frequenz ermitteln kann und es sicher gestellt ist das die CPU nicht gedrosselt ist, kann man mit wenig Aufwand sehr präzise Zeitmessungen Vornehemen. Bei einer einzelnen Messung besteht aber die Gefahr, dass eine (oder mehrere) context switch das Ergebnis verzerrt.



  • stoppuhr schrieb:

    Könntest du bitte den Test clock_gettime.c kopieren und die ganze Testreihe um ein normales CLOCK_MONOTONIC erweitern, damit man sehen kann wie sehr sich die CLOCK_MONOTONIC_COARSE Version von der anderen unterscheidet. Danke!

    Steigt mit CLOCK_MONOTONIC von 6 auf 25 ns (Core i5, 64 bit).

    nativ schrieb:

    Bei einer einzelnen Messung besteht aber die Gefahr, dass eine (oder mehrere) context switch das Ergebnis verzerrt.

    Und damit der Scheduler nicht spontan auf die Idee kommt, deinen Thread auf eine andere CPU mit anderem Zählerstand zu verlagern, musst du den Thread auf eine bestimmte CPU einfrieren. Normalerweise ist das keine gute Idee.

    Das Szenario ist für mich auch nicht ganz überschaubar, aber es bleibt nach wie vor der Ansatz, der in den Tests "cached_time" heisst. Da es für mich so klingt, als ob du im wesentlichen feststellen willst, ob deine Abarbeitungszeiten in Einzelfällen von den regulären Mikrosekunden in den Sekundenbereich abdriften, dürfte eine niedrige Auflösung wie 0.2s oder gar 1s ausreichen, womit dein Zeit-Thread nicht öfter als 5 bzw. 1 mal pro Sekunde zum Aktualisieren aufwachen muss und damit quasi keine Zusatzlast erzeugt.



  • Welche genauen Kernel- und Libc-Versionen benutzt du denn?



  • peterpeterpeter schrieb:

    Welche genauen Kernel- und Libc-Versionen benutzt du denn?

    Falls du mich meintest, auf dem Intel-Notebook:
    `ldd (Ubuntu EGLIBC 2.17-93ubuntu4) 2.17

    3.11.0-12-generic`

    Auf dem Desktoprechner so was ähnliches (Ubuntu 13.04 mit kernel 3.11 RC6 oder so).
    Übrigens, der Vollständigkeit halber: auch auf dem Desktop dauert clock_gettime(CLOCK_MONOTONIC_COARSE) im 64-bit-Modus nur 7 ns.



  • nativ schrieb:

    Zumindest für die x86-32/64 Architekturen würde sich inline Assembler als Alternative anbieten: es gibt den Befehl RDTSC (read time stamp counter), der den aktuellen Wert eines 64Bit Zählers ausliest, der mit jede Taktzyklus der CPU inkrementiert wird. Wenn man die maximale CPU Frequenz ermitteln kann und es sicher gestellt ist das die CPU nicht gedrosselt ist, kann man mit wenig Aufwand sehr präzise Zeitmessungen Vornehemen. Bei einer einzelnen Messung besteht aber die Gefahr, dass eine (oder mehrere) context switch das Ergebnis verzerrt.

    ein mitarbeiterkollege hat damit schon vor einigen jahren herumexperimentiert und hatte genau die angesprochenen probleme. leider 😞

    asfas schrieb:

    Steigt mit CLOCK_MONOTONIC von 6 auf 25 ns (Core i5, 64 bit).

    Danke.

    peterpeterpeter schrieb:

    Welche genauen Kernel- und Libc-Versionen benutzt du denn?

    und falls du mich meinst 🙂 wie auf der vorseite ersichtlich:

    Stoppuhr schrieb:

    ./time                       time per call: 298 nanoseconds
    ./ftime                      time per call: 450 nanoseconds
    ./gettimeofday               time per call: 403 nanoseconds
    ./clock_gettime_mono         time per call: 390 nanoseconds
    ./clock_gettime_mono_coarse  time per call: 344 nanoseconds
    ./clock_gettime_mono_raw     time per call: 389 nanoseconds
    ./clock_gettime_real         time per call: 385 nanoseconds
    ./clock_gettime_real_coarse  time per call: 337 nanoseconds
    
    # ldd --version
    ldd (Ubuntu EGLIBC 2.15-0ubuntu10.5) 2.15
    
    # gcc --version
    gcc (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
    
    # cat /proc/cpuinfo
    model name      : Intel(R) Core(TM)2 CPU          6400  @ 2.13GHz
    model name      : Intel(R) Core(TM)2 CPU          6400  @ 2.13GHz
    
    # uname -r
    3.2.0-38-generic
    
    cat /proc/self/maps
    vdso wird angezeigt, wenn die test laufen
    
    # cat /sys/devices/system/clocksource/clocksource0/available_clocksource
    tsc hpet acpi_pm
    
    # cat /sys/devices/system/clocksource/clocksource0/current_clocksource
    tsc
    


  • ich habe gestern kurz mit einer aktuellen Ubuntu LiveCD herumgespielt

    ./time                         time per call: 138 nanoseconds
    ./ftime                        time per call: 283 nanoseconds
    ./gettimeofday                 time per call: 241 nanoseconds
    ./clock_gettime_mono           time per call: 239 nanoseconds
    ./clock_gettime_mono_coarse    time per call: 199 nanoseconds
    ./clock_gettime_mono_raw       time per call: 237 nanoseconds
    ./clock_gettime_real           time per call: 240 nanoseconds
    ./clock_gettime_real_coarse    time per call: 193 nanoseconds
    
    ldd --version
    ldd (Ubuntu EGLIBC 2.17-93ubuntu4) 2.17
    
    gcc --version
    gcc (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.1
    
    cat /proc/cpuinfo
    model name	: Intel(R) Core(TM)2 CPU          6400  @ 2.13GHz
    model name	: Intel(R) Core(TM)2 CPU          6400  @ 2.13GHz
    
    uname -r
    3.11.0-12-generic
    
    cat /sys/devices/system/clocksource/clocksource0/available_clocksource
    tsc hpet acpi_pm 
    
    cat /sys/devices/system/clocksource/clocksource0/current_clocksource
    tsc
    

    Ich finde werte sehr interessant, da es ja die gleiche Hardware ist.
    Liegt es nun am Kernel oder an der glibc? Bei der glibc hat sich im Bereich Clock* einiges getan.

    Eigentlich passt diese Frage nicht unbedingt hier rein, aber gibt es eine Möglichkeit, dass man bei einer LiveCD selbst irgendwie Kernel und glibc-Version auswählt und sich so eine LiveCD selbst erstellt?



  • Eigene Live-CDs erstellen ist relativ simpel, ich mache das manchmal für den Eigenbedarf mit http://grml.org, weil da die Tools und Doku auch sehr gut sind.

    Debian (und somit auch Ubuntu) verwendet schon seit geraumer Zeit nicht mehr die glibc sondern die eglibc, du kannst ja mal die Changelogs lesen.

    Aber warum linkst du nicht einfach mal gegen die dietlibc oä. und probierst es so aus? Eine andere Kernelversion kannst du ja auch leicht in Grub angeben; Distro von der CD, x-beliebigen Kernel von der Festplatte.



  • wenn man auf l*n*x unterwegs ist, läßt sich die CPU Last von Programmen mit Hilfe eines kleinen Tools begrenzen, ohne daß man irgendwas am Programm ändern muß:

    cpulimit -l 10 bla.exe  # Lastgrenze 10%
    

Anmelden zum Antworten