CPU-timer in threads...



  • allo zusammen,

    hoffentlich kann mir jemand von euch helfen...
    Ich habe da ein Problem mit der Zeitmessung auf verschiedenen Linux und Unix-Systemen...

    Ersteinmal, was ich gerne haette:
    Ich arbeite an einem Programm was ich mittels pthreads parallelisieren moechte. Dafuer moechte ich so ein paar Zeiten messen.
    Einmal die Zeit, die das Programm insgesamt laeuft: kein Problem benutze ich die real-Zeit.
    Dann haette ich gerne die CPU aller threads gemessen: das habe ich noch nicht so ganz geschafft, da es da wohl von System zu System Unterschiede gibt... Aber das soll hier nicht das Problem sein...

    Mein Problem ist nun: Ich haette gerne die CPU-Zeit eines Threads gemessen. Das ging bis zum Kernel 2.4 mit: times()
    Ab Kernel 2.6 liefert times() die komplette CPU-Zeit des Prozesses. (ok... das hat es auch schon vorher getan, jedoch war da ein threadein eigener Prozess)...
    Ich habe schon einiges versucht. Darunter war auch folgender Versuch:
    - mit clock_gettime(CLOCK_THREAD_CPUTIME_ID, ..) die Zeit messen...
    - die Zeit aus /proc/self/task/*ID*/stat auslesen
    - mit clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ..) die Zeit zu messen...

    Das Testprogramm hat 10 Threads auf einem 8 Prozessor-Server gestartet und die Threads ein wenig beschaefftigt. Dabei waren die Zeiten gemessen mit CLOCK_THREAD_CPUTIME_ID und CLOCK_PROCESS_CPUTIME_ID fast identisch und die Zeit aus /proc/... war teilweise um mehrere Sekunden geringer...

    Hier mal eine Zeile meines Testprogramms:
    thread: 6.470 ausgelesen aus /proc/...
    cpu: 10.220 gestartet mit CLOCK_PROCESS_...
    times: 72.420 gestartet mit times()
    thread2: 10.219 gestartet mit CLOCK_THREAD_...

    Kernel: 2.6.10

    Mein Hilfeersuchen nun an euch:
    1. Weiss jemand, wie ich unter Linux den Verbrauch an CPU-Zeit eines einzelnen Threads ermitteln kann...??? Das Auslesen der /proc/...steht da nicht zur Debatte.
    2. Weiss jemand wie das selbe Problem unter AIX 5.1 behandelt werden kann..???

    Danke fuer eure Hilfe

    Gruss
    Christian



  • Hallo,

    um Informationen über benutze Ressourcen von Threads bzw. Prozessen zu erhalten gibt es unter BSD, SVR4 und Linux die Funktionen wait3 und waiot4, sie sind aber nicht Bestandteil von POSIX.1.

    wait3 sollte nicht bentuztz werden da es anders als die wait4 Funktion dem Benutzer nicht die Möglichkeit gebene wird festzulesen auf welchen Thread bzw. Prozess gewartet werden soll.

    pid_t wait4(pid_t pid, int *status, int opntionen, struct rusage *usage);
    Funktion gibt Prozess-ID bei Erfolg und -1 bei Fehler

    Die Struktur rusage enthält die Informationen über die benutzen Ressourcen des beendenen Prozesse, wie z.B verbrauchte CPU-Zeit, anzahl der empfangenen Signale usw. Näheres findest du in der manpage von getrusage

    dann gibt es noch die Funktion times, mit der du ja anscheinend keinen erfolg hattest.

    clock_t times(struct tms *cpu_zeit);

    struct tms {
    clock_t tms_utime; // Benutzer-CPU Zeit
    clock_t tms_stime; // System CPU Zeit
    clock_t tms_cutime; // Benutzeer CPU Zeit der beendet. Kindproz.
    clock_t tms_cstime; // System-CPU-Zeit der beendet. Kindproz.
    }

    Eins ist vieleicht noch wichtig die letzen beiden Einträge erhalten nur die Werte von Kindprozessen, auf deren Beendigung man gewartet hat(wait, waitpid)



  • AIX hat viele Zeitfunktionen, leider weiss ich sie nicht mehr alle, aber ich bin sicher, es gibt da so eine Funktion.

    Probier mal clock() aus der C-Standard-Library. AIX 4.2 hat beim Aufruf von clock() in einer Schleife immer denselben Wert zurueckgeliefert. Weiss nicht, ob das noch so ist. Aber wenn Du clock() in groesseren Abstaenden zwischen Wartezeiten aufrufst, duerfte es kein Problem sein.

    clock() kann auch unter Linux Dein Retter sein. 😉



  • Da wirst du wohl auch was Linux-spezifisches brauchen, also ab ins Linux-Forum ;).



  • Dieser Thread wurde von Moderator/in AJ aus dem Forum ANSI C in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • asdasdasd schrieb:

    pid_t wait4(pid_t pid, int *status, int opntionen, struct rusage *usage);
    Funktion gibt Prozess-ID bei Erfolg und -1 bei Fehler

    Die Struktur rusage enthält die Informationen über die benutzen Ressourcen des beendenen Prozesse, wie z.B verbrauchte CPU-Zeit, anzahl der empfangenen Signale usw. Näheres findest du in der manpage von getrusage
    )

    Das ist schon richtig, aber wait4 gibt dir die Informationen für Childprozesse und nicht für Threads innerhalb des laufenden Programmes. Threads werden ja auch nicht mit wait4() wieder mit dem Hauptprogramm vereinigt sondern mit pthread_join().

    So wie ich das verstanden habe, möchte mcr innerhalb eines laufenden Threads messen wieviel CPU Zeit zwischen zwei Programmpunkten innerhalb dieses laufenden Threads verbraten wurde. Das Problem ist, dass ab NPTL alle Methoden die verbratene CPU zeit liefern, die alle Threads gemeinsam gebraucht haben.

    Die einzige mir bekannte Möglichkeit, ist die Information aus /proc herauszulesen, da dies dort separat geführt wird. Das kann aber in einigen Fällen viel zu langsam sein.



  • @Power off
    Alle Funktionen, mit denen man unter Aix die CPU-Zeit messen kann, beziehen sich meines Wissens nach auf den gesamten Prozess und nicht auf einen einzelnen Thread.

    @Ponto
    Stimmt... Ich moechte innerhalb eines Threads sagen koennen, wie viel CPU-Zeit alleine fuer diesen Thread verstrichen ist. Ich moechte auch nicht warten muessen, bis der Thread sich beendet hat.

    Ich hoffe, es gibt noch andere Ideen...

    Danke
    mcr



  • Also 1.

    NOTE for SMP systems
    The CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID clocks are
    realized on many platforms using timers from the CPUs (TSC on i386,
    AR.ITC on Itanium). These registers may differ between CPUs and as a
    consequence these clocks may return bogus results if a process is
    migrated to another CPU.

    If the CPUs in an SMP system have different clock sources then there is
    no way to maintain a correlation between the timer registers since each
    CPU will run at a slightly different frequency. If that is the case
    then clock_getcpuclockid(0) will return ENOENT to signify this condi-
    tion. The two clocks will then only be useful if it can be ensured that
    a process stays on a certain CPU.

    The processors in an SMP system do not start all at exactly the same
    time and therefore the timer registers are typically running at an off-
    set. Some architectures include code that attempts to limit these off-
    sets on bootup. However, the code cannot guarantee to accurately tune
    the offsets. Glibc contains no provisions to deal with these offsets
    (unlike the Linux Kernel). Typically these offsets are small and there-
    fore the effects may be negligible in most cases.

    2. es heisst es ja THREAD_CPUTIME also die Zeit des Threads auf einer CPU. also muesste bei 10 threads auf 8 CPUs statistisch gesehen jeder thread 8/10 der Prozesszeit haben?


Anmelden zum Antworten