Auf welchem Processor läuft mein Thread



  • Hallo Freaks,

    ich möchte mit PdhAddCounter( hQuery, L"\\Processor(0 oder 1)\% Processor Time", .. ) und anschließendem PdhGetFormattedCounterValue die Processor-Last von dem Processor abfragen, auf dem mein aktueller Thread gerade läuft.
    Wie bekomme ich aber bei einer Multiprocessor-Maschine die Processor-Nr. in Abhängigkeit des Threads heraus?

    Fragt
    Werner



  • Hi Freak,

    Wie wäre es mit GetThreadGroupAffinity()? Hilft dir das eventuell weiter!?



  • freak0r schrieb:

    Wie wäre es mit GetThreadGroupAffinity()? Hilft dir das eventuell weiter!?

    .. kann das sein, dass das erst ab Windows 7 unterstützt wird!? Ich bräuchte es für Windows XP.



  • Warum willst Du das?
    Was hilft es Dir wenn Du *jetzt* den Prozessor weist, aber nachdem die Funktion zurückgekehrt ist, läuft Dein Thread auf dem anderen...

    Ich schlage vor:
    1. Verlass Dich auf den Windows-Scheduler...
    2. Du kannst Dein Thread nur langsamer machen, und niemals schneller
    3. Du kannst Deinen Thread nur auf bestimmte Prozessoren *begrenzen*; das hält aber andere Threads nicht davon ab, dass die auch auf diesem Prozessor laufen

    Wenn Dir das nicht gefällt, musst Du das OS wechseln.



  • Jochen Kalmbach schrieb:

    Warum willst Du das?

    Hallo Jochen,

    ich suche immer noch einen Fehler in dem Programm an dem ich arbeite. Er äußerte sich bisher so, dass ein ganz bestimmter Timer nach einem WaitForMultipleObjects nicht in den Zustand signaled geht. (siehe auch meine bisherigen Threads hier und hier)
    Was wir bisher festgestellt haben haben ist, das ein anderer Thread die CPU-Last zeitweise auf 100% zieht; ich konnte jedoch bisher nicht sicher verifizieren, dass der hängende Timer damit in Zusammenhang zu bringen ist. Meine Idee war, beim Aufwecken des Threads nach dem WaitForMultipleObjects die aktuelle CPU-Last auszugeben, nur um bestätigt zu bekommen, dass die CPU jetzt gerade anderweitig beschäftigt ist, während der Timer hängt oder eben nicht - also nur für Debug-Zwecke, um Licht ins Dunkle zu bringen.

    Jochen Kalmbach schrieb:

    Was hilft es Dir wenn Du *jetzt* den Prozessor weist, aber nachdem die Funktion zurückgekehrt ist, läuft Dein Thread auf dem anderen...

    Erstens wusste ich nicht, dass das überhaupt passieren kann, und zweitens habe ich das noch nie beobachtet, und drittens wäre das für meine Anwendung auch egal, solange ein Prozessor-Wechsel nicht alle paar Sekunden auftritt.

    Jochen Kalmbach schrieb:

    Ich schlage vor:
    1. Verlass Dich auf den Windows-Scheduler...

    tue ich sowieso, da bin ich ganz Deiner Meinung

    Jochen Kalmbach schrieb:

    2. Du kannst Dein Thread nur langsamer machen, und niemals schneller

    ist nicht meine Intuition (s.o.)

    Jochen Kalmbach schrieb:

    3. Du kannst Deinen Thread nur auf bestimmte Prozessoren *begrenzen*; das hält aber andere Threads nicht davon ab, dass die auch auf diesem Prozessor laufen

    logisch! allein mein Prozess (einer von mindestens vier Anwenderapplikationen, die zu dem Zeitpunkt gleichzeitig auf der Maschine laufen, hat mehr als hundert Threads.

    Jochen Kalmbach schrieb:

    Wenn Dir das nicht gefällt, musst Du das OS wechseln.

    Für professionelle Anwendungen ist das ein frommer Wunsch.

    Aber Danke für die Antwort, vielleicht hast Du noch eine Idee wie ich da weitersuchen kann. Dummerweise tritt dieser Fehler auch noch sehr selten auf. Und ich bin immer auf die Trace-Ausgaben angewiesen, die ich manchmal erst nach einer Woche erhalte.

    Gruß
    Werner



  • Werner Salomon schrieb:

    dass ein ganz bestimmter Timer nach einem WaitForMultipleObjects nicht in den Zustand signaled geht.

    Warum soll ein Timer in den Zustand "Signal" gehen? Was hat das mit "WaitForMultipleObjects zu tun?
    Wenn Du ein Event-Handle dem WaitForMultipleObjects übergibts, kann es höchstens sein, dass der Event anschließend "Resetet" wurde... oder hast Du "ManualReset" aktiviert? Das sollte man nur in den seltensten Fällen machen!
    Du übergibst ja auch noch andere Handles dem WaitForMultipleObjects... was sind das für welche?

    PS: Wie äußert sich der Fehler! Kannst Du es irgendwie erkennen? Kannst Du einen Dump erzeugen? Kannst Du es bei Dir nachvollziehen?

    Werner Salomon schrieb:

    und drittens wäre das für meine Anwendung auch egal, solange ein Prozessor-Wechsel nicht alle paar Sekunden auftritt.

    Je nach Auslastung tritt ein Prozessorwechseln i.d.R. alle paar 100 ms auf...



  • Jochen Kalmbach schrieb:

    Werner Salomon schrieb:

    dass ein ganz bestimmter Timer nach einem WaitForMultipleObjects nicht in den Zustand signaled geht.

    Warum soll ein Timer in den Zustand "Signal" gehen? Was hat das mit "WaitForMultipleObjects zu tun?

    Hallo Jochen,
    da habe ich mich unklar ausgedrückt. Wir benutzen die Waitable Timer von Windows. Mit CreateWaitableTimer wird ein HANDLE erzeugt und dies an die HANDLE-Liste in WaitForMultipleObjects übergeben.

    Jochen Kalmbach schrieb:

    Wenn Du ein Event-Handle dem WaitForMultipleObjects übergibts, kann es höchstens sein, dass der Event anschließend "Resetet" wurde... oder hast Du "ManualReset" aktiviert? Das sollte man nur in den seltensten Fällen machen!

    Nein - natürlich ist ManualReset immer FALSE, sowohl bei den Timern als auch den Events. Was anderes macht kaum Sinn.
    Das komische ist ja auch, dass der Timer-handle irgendwann kommt, aber eben viel zu spät (nach ca. 8-14s). Und ich lasse mir inzwischen auch die Zeit im SetWaitableTimer ausgeben, die ist definitiv korrekt (immer 8ms). Im gleichen Thread wird während der besagte Timer hängt ein zweiter Timer in die Handle-Liste eingetragen, steht also hinter dem besagten, und wird aber vorher als 'signaled' erkannt, obwohl seine Timerzeit länger ist und er später eingetragen wurde.

    Jochen Kalmbach schrieb:

    Du übergibst ja auch noch andere Handles dem WaitForMultipleObjects... was sind das für welche?

    Drei Events (aus CreateEvent) der Rest Timer-Handles (s.o.)

    Jochen Kalmbach schrieb:

    PS: Wie äußert sich der Fehler! Kannst Du es irgendwie erkennen? Kannst Du einen Dump erzeugen? Kannst Du es bei Dir nachvollziehen?.

    Der Fehler äußert sich letztlich in einer Exception, die vom Programm ausgelöst wird, weil ein Zustand eintritt der nicht vorgesehen war. Durch den hängenden Timer wird in einer anderen Anwendung ein Timeout ausgelöst, auf Grund dessen versucht wird, den aktuellen Vorgang abzubrechen. In diesem Mechanismus ist wahrscheinlich auch ein Fehler, was dann zu der Exception führt, aber eben nur ein Folgefehler.
    Debuggen kann ich es gar nicht. Es ist in den letzten 10Tagen genau zweimal aufgetreten, bei ca. einem halben Dutzend Maschinen, die mit Unterbrechungen ständig laufen. Das erste Mal nach 47Stunden und das zweite Mal nach 11Minuten, nachdem der jeweilige Rechner gestartet wurde. Ich habe nur Traces zur Verfügung, die ich aber selber erweitern kann - daher auch die Idee mit der Ausgabe der CPU-Last.

    Jochen Kalmbach schrieb:

    Werner Salomon schrieb:

    und drittens wäre das für meine Anwendung auch egal, solange ein Prozessor-Wechsel nicht alle paar Sekunden auftritt.

    Je nach Auslastung tritt ein Prozessorwechseln i.d.R. alle paar 100 ms auf...

    Interessante Sache, da kenne ich mich gar nicht mit aus. Kann man sich da irgendwo in das Thema einlesen?

    Gruß
    Werner



  • 8 ms !?
    Windows ist kein Echtzeit OS! ALso lebe in 1% der Fälle mit Werten > 500 ms...



  • Jochen Kalmbach schrieb:

    8 ms !?
    Windows ist kein Echtzeit OS! ALso lebe in 1% der Fälle mit Werten > 500 ms...

    Ich weiß .. nach unseren Erfahrungen machen Timerzeiten bis runter zu 5ms durchaus noch Sinn. Wenn es dann doch irgendwann länger dauert, dann ist es in dem speziellen Fall erst ab 5s wirklich ein Problem, weil dann die Timeouts zuschlagen.
    Zur Hintergrundinformation: Der Teil mit den Timern wurde von uns vor ca. 7 Jahren entwickelt. Damals noch unter Windows NT und lief seitdem praktisch unverändert und ohne Probleme. Die Timerzeiten ließen sich auch in der Praxis sehr gut einhalten, falls die CPU-Last in Summe so ca. 60% nicht überschritt.

    Hast Du zu den anderen Punkten noch eine Idee?

    Gruß
    Werner


Anmelden zum Antworten