Thread Sheduling Änderungen von Windows XP nach Windows 7



  • Nach deiner Beschreibung müsste WaitformultibleObjectsEx an Position 8 *sofort* zurückkommen, da der Event ja schon signaled ist bevor WaitformultibleObjectsEx überhaupt aufgerufen wird.

    Da stimmt also irgendwas nicht.

    Entweder du misst die Gesamt-Zeit, dann kannst du auch nicht wissen welcher Schritt nun so lange dauert => finde raus welche Schritte wie lange dauern.
    Oder es läuft da von Anfang an irgend was faul, da wie gesagt WaitformultibleObjectsEx - wenn ich deine Beschreibung richtig verstehe - da immer sofort zurückkehren müsste.

    Zeig vielleicht mal den relevanten Code her...



  • als ich kann in der Beschreibung von WaitformultibleObjectsEx nicht lesen ob der Thread da nicht die Rechenzeit abgibt. Und ein anderer Thread drankommt, da steht nur das er selbst im running bleibt oder sich schlafen legt aber ob er dann wirklich weiter läuft wenn er running ist steht da nichts



  • Auch wenn der Thread die Rechenzeit kurz abgeben sollte, so darf das weder 150 ms noch 450 ms dauern; sondern max 15 ms... Es sei Denn Du hast natürlich 450/15 (also 30) Threads laufen, die Ständig etwas tun. Aber dann wäre Dein Design etwas miserabel...

    Also, da ist noch irgendwas anderes, was Dein Problem verursacht. Zeig mal _genau_ den Code wie Du die Zeit misst...



  • Hallo Jochen,

    also mit deinen 30 Threads könntest du traurigerweise schon recht haben und das Design als Miserabel zu bezeichnen ist noch schmeichelnd. Es hat nur dieser eine eine höhere Priorität.

    Die Zeit messe ich mit Timestamp::CurrentSys() aber es war noch nicht vor und nach dem waitforsingleobjectex sondern iorgendwo im Ablauf. Ich habe nur im Ablauf keine weitere Funktion enddekt die irgendwie Blocken könnte.

    MfG



  • Du solltest die Zeiten mit "QueryPerformanceCounter" messen. Sonst hast Du viel zu hohe Ungenauigkeiten.
    Auch empfehle ich Dir ein "timeBeginPeriod(1)" am Anfang der App aufzurufen. Das benötigt aber Admin-Rechte!



  • Hallo Jochen,

    also ich wieß jetzt nicht was das Problem mit der Zeitmessung zu tun hat es kommt ja nicht genau auf die Millisekunde drauf an auch eine ungenauigkeit von 50 ms stört micht nicht nur halt wenn die zeit sich verdoppelt oder verdreifacht und da sollte doch die Zeitmessung ausreichend sein.

    MfG



  • Mit der Zeitmessung hat es nichst zu tun... Ich würde Dir trotzdem raten eine genauere Methode zu nehmen die unabhängig von irgendwelchen Zeitservern ist...



  • Jochen Kalmbach schrieb:

    Du solltest die Zeiten mit "QueryPerformanceCounter" messen. Sonst hast Du viel zu hohe Ungenauigkeiten.
    Auch empfehle ich Dir ein "timeBeginPeriod(1)" am Anfang der App aufzurufen. Das benötigt aber Admin-Rechte!

    Was für einen Vorteil hätte er von timeBeginPeriod(1), wenn er QueryPerformanceCounter() verwendet, außer dass evtl. noch mehr Zeit für Contextswitches draufgeht? Für seine Zwecke sollte doch sogar schon GetTickCount() ausreichend sein!? Möglicherweise ist auch QueryThreadCycleTime() hilfreich!?



  • also mal zurück zum Thema.

    Welche Winapi aufrufe Kosten in Windows7 mehr zeit als ind XP?

    MfG



  • Destiniy schrieb:

    Welche Winapi aufrufe Kosten in Windows7 mehr zeit als ind XP?

    Hat dein Problem denn mit der Zeitdauer irgendwelcher API Calls zu tun? Falls ja: Wie hast du das herausgefunden? Wenn du richtig profiled hast, solltest du sowieso wissen, wo genau die Zeit vergeht!?



  • Hallo

    leider weiß ich noch nicht so genau wo die Zeit vergeht, da ich dafür erst mal mit Hilfe von Logs das Problem eingrwenzen muß. Und das dauert da bei jedem Versuch erst mal einer 300 km entfernt das Programm auf der Maschine laufen lassen muß. (3 h pro Versuch)

    ich vermute nur dass es API calls sind, da es ja auf Windows XP nicht auftritt:

    MfG



  • Hallo,

    also das Problem ist nicht das WaitForMultipleObjectsEx so lange braucht es kommt nur zu offt mit dem Event WAIT_IO_COMPLETION zurück kann es sein das Windows 7 die WSARecv Completition Routine viel öffter mit kleineren häppchen aufruft?

    MfG



  • dot schrieb:

    Was für einen Vorteil hätte er von timeBeginPeriod(1), wenn er QueryPerformanceCounter() verwendet

    Das eine hat mit dem anderen nichts zu tun...



  • Destiniy schrieb:

    also das Problem ist nicht das WaitForMultipleObjectsEx so lange braucht es kommt nur zu offt mit dem Event WAIT_IO_COMPLETION zurück kann es sein das Windows 7 die WSARecv Completition Routine viel öffter mit kleineren häppchen aufruft?

    Das ist leicht möglich.
    Und was genau bereitet dabei jetzt Probleme, wenn WaitForMultipleObjectsEx zu oft mit WAIT_IO_COMPLETION zurückkommt?



  • es scheint so als geht WAIT_IO_COMPLETION vor den anderen Events

    also das event auf das ich warte wird gesetzt, und bevor es ausgelöst wird kommen so 30 WAIT_IO_COMPLETION events vorher



  • Destiniy schrieb:

    es scheint so als geht WAIT_IO_COMPLETION vor den anderen Events

    also das event auf das ich warte wird gesetzt, und bevor es ausgelöst wird kommen so 30 WAIT_IO_COMPLETION events vorher

    Ja, ist ja auch ganz normal - wenn APCs anstehen und man "alertable" wartet, dann werden halt erstmal die APCs abgearbeitet.

    Die Frage ist: warum sind 30 APCs vor der "erwünschten" Nachricht ein Problem? Dauert das Abarbeiten der APCs so lange?
    Wenn ja dann hast du da ein grundlegendes Problem, nämlich dass weniger wichtige APCs abgesetzt werden, die dann wichtigere Ereignisse verzögern.

    U.u. könnte man sich mit einem Hack behelfen: wenn du die Abarbeitung von bestimmten Events bevorzugt machen willst, dann prüf einfach vor dem "alertable" WaitForMultipleObjectsEx mit einem "nicht alertable" WaitForMultipleObjectsEx nur diese bevorzugten Events.
    Also z.B. so:

    // Erst die wichtigen Events mit timeout = 0 und alertable = false prüfen
    // (Die wichtigen Events müssen dabei dir ersten in "allEvents" sein. Dadurch brauchen wir nur ein Array, und vor allem bedeutet dann der Returnwert immer das selbe,
    //  wir können also das selbe switch() verwenden egal welcher WaitForMultipleObjectsEx() das Ergebnis geliefert hat)
    DWORD rc = WaitForMultipleObjectsEx(importantEventsCount, allEvents, false, 0, false);
    // Wenn nichts wichtiges anliegt normal warten
    if (rc == WAIT_TIMEOUT)
        rc = WaitForMultipleObjectsEx(allEventsCount, allEvents, false, timeout, true);
    switch (rc)
    {
        ...
    

    p.s.: Falls das zu unerwünschten Nebeneffekten führt, z.B. andere Dinge zu arg verzögert, dann hilft vielleicht wenn das "importantEvents" WaitForMultipleObjectsEx nur bei jedem 2. Durchlauf gemacht wird. Wenn permanent APCs und "wichtige" Events anstehen würden die APCs dann nicht ausgehungert, sondern immer ein APC, ein Event, ein APC, ein Event etc. abgearbeitet.



  • Jochen Kalmbach schrieb:

    dot schrieb:

    Was für einen Vorteil hätte er von timeBeginPeriod(1), wenn er QueryPerformanceCounter() verwendet

    Das eine hat mit dem anderen nichts zu tun...

    Eben, da ich die API aber nur im Zusammenhang mit der Genauigkeit von gewissen Timern kenne und nur weiß, dass sie im Prinzip den Heartbeat des Schedulers erhöht, würde mich interessieren, was genau man in dem Fall hier davon hat bzw. haben könnte, rein aus Interesse.



  • Wenn man den Heartbeat des Schedulers erhöht, so erhöht sich automatisch auch die Reaktionszeit von Waitable-Objects... als ein WaitFor...Object wird somit "schneller"...
    Das ganze hängt natürlich auch noch von den anzahl der ReadyToRun Threads ab... also wenn _keine_ ReadyToRun sind, dann merkt man keinen Unterschied. Aber wenn es mehrere sind, dann kann es schon was ausmachen, da jeder Thread ja öfter unterbrochen wird.... aber es hat, wie Du ja auch sagtest, Nachteile, wenn sehr viele Threads laufen. Wenn man aber gescheit programmiert hat man mehr Vorteile als Nachteile; zumindest aus meiner Erfahrung... und ich mache schon lange unter Windows mit Echtzeitsteuerung rum... aber hier meistens mit Fibers, da hier das (User-Mode) Scheduling noch schneller ist 😉



  • Jochen Kalmbach schrieb:

    also wenn _keine_ ReadyToRun sind, dann merkt man keinen Unterschied.

    Hm.
    Müsste das nicht genauer heissen "wenn keine ReadyToRun Threads mit gleicher Priorität da sind"?
    Threads mit niedrigerer Priorität sollten - wenn ich das Windows' Scheduling richtig verstehe - sofort unterbrochen werden. Und Threads mit höherer laufen so oder so weiter.

    Sonst würden einem vielbeschäftigte Background Threads ja die ganze Performance weglutschen. Das wäre Übel.



  • Ja, mir "gleicher und höherer Prio".

    Wobei man sagen muss, dass die meisten Synchronisations-Objekte von *User-Mode* Threads signalisiert werden. Somit ann man nicht sagen, dass nieder priore Threads sofort unterbroichen werden, wenn das Ereignis eintritt. Weil das ereignis ja vielleicht schon viel früher eingetreten ist, aber der nieder priore Thread erst später drankommt um einen möglicherweise höher prioren thread zu signalisieren.... aber jetzt wird es mehr theoretisch und dann spielt natürlich auch noch das dynamische erhöhen der Prio für solche Dinge eine Rolle. Das geht ja aber nur bis prio 15... ab prio 16 gibt es keine dynamische Erhöhung um solche Fälle besser abhandeln zu können...

    Meine Threads laufen alle mit Prio 32 😉 und dann via Fibers gescheduled... dann muss man sich auch keine Sorgen um Synchronisation machen 😉


Anmelden zum Antworten