Thread Sheduling Änderungen von Windows XP nach Windows 7



  • Hallo Leute,

    ich habe ein Programm mit sehr vielen Klassen die alle Threads zur Kommunikation bzw. zur bearbeitung von verschieden Steuerungsaufgaben anlegen. Jetzt habe ich einen Core2Duo industrie PC mit Windows XP. Alles läuft wunderbar.

    Wenn ich auf Windows 7 mit dem selben PC wechsel ist die Anwendung viel langsamer. Eins besipiel um ein Druckwerk zu steueren dauert der Empfang einer NAchticht bis zum neuen Befehl (mit allen Events Threadwechseln usw.) an das Druckwerk mit Windows XP zwischen 130 und 150 ms. Genau das selbe auf windows 7 dauer zwischen 450 und 650 ms.

    Hat sich in dem Windows Taskmodell etwas Grundlegend verändert?

    MfG



  • Destiniy schrieb:

    Hat sich in dem Windows Taskmodell etwas Grundlegend verändert?

    Naja, das System an sich und natürlich insbesondere das Scheduling wurde ab Windows Vista+ afaik grundlegend umgebaut und skaliert wesentlich besser. Wenn du allerdings nur wenige (zwei) Cores hast, kann es schon sein, dass sich dadurch sogar kleine Nachteile ergeben. Ich könnte mir allerdings auch vorstellen, dass sich der Synchronisierungsoverhead in deiner Anwendung einfach mit dem Scheduling von Windows 7 erst richtig bemerktbar macht...



  • Hallo

    ich denke auch das es irgenwie an der Synchronisierung der Threads liegt. Wodurch passiert es dann, dass sich das in Windows 7 so stark äußert?

    Das ganze Programm ist eine Riesengroße Sammlung von Klassen die untereinander Stark vermischt, nicht mehr nachvollziehbar was welche Klasse macht? Es gibt keine Trennung der Schichten mehr, da immer wieder irgendwelche Änderungen vorgenommen wurden.

    Ich suche einfach nach den offensichtlichsten Stellen z.B.: habe ich schon einen Blockierenden Funktionsaufruf in einem Windows Callback gefunden

    Vielleicht habt ihr ja noch ein paar Ideen nach was ich noch schauen kann?

    MfG



  • Eine Änderung die mir jetzt spontan einfällt betrifft CRITICAL_SECTION .
    Unter Windows XP waren die noch mehr oder weniger FIFO-Mutexen.

    D.h. wenn du einen Thread A hast, der schon längere Zeit auf die CRITICAL_SECTION wartet, während Thread B sie gerade gelockt hat.
    (Wobei "schon längere Zeit" heisst dass er nicht mehr "spint" sondern schon sich schon schlafen gelegt hat)

    Wenn dann Thread B die CRITICAL_SECTION freigibt, und sofort danach die selbe CRITICAL_SECTION wieder locken will, dann bekommt unter Windows XP einigermassen zuverlässig Thread A die CRITICAL_SECTION , weil er am längsten wartet.

    Ab Vista bekommt dann meistens Thread B wieder Zugriff. Bzw. es kann sogar ein ganz anderer Thread C Zugriff bekommen, der auch zu dem Zeitpunkt wo die CRITICAL_SECTION von B freigegeben wird daherkommt und locken will.

    Bei den meisten Programmen sollte das keinen Unterschied machen, aber es gibt natürlich Fälle wo sich das Vista+ Verhalten negativ auswirkt. Im schlimmsten Fall kann das ein Programm quasi komplett zum Stillstand bringen.

    (Das quasi-FIFO Verhalten unter Windows XP war übrigens nie garantiert, nur dass sich dummerweise etliche Programmierer darauf verlassen.)



  • Hallo Leute,

    ich abe mich jetzt genau ion dieses Problem reingefitzt. Es esistieren zwei Socketz die die Kummunikation zu 2 devices machen. Diese Sockets empfangen Daten über eine Readfilecompletition Routine und setzen da eins Receivevent. Des weiteren existiert noch ein Steuerthread der über 10 Klassen daten und Befehle an die Deveices gibt. Dieser Steuerthread hat ein WaitformultibleObjectsEx.

    Jetzt ist folgender Ablauf:

    1. WaitformultibleObjectsEx kehrt zurück event starte erstes device gesetzt
    2. ertes device wird gestartet
    3. erstes device Antwortet bin gestartet
    4. Socket löst Read Event aus.
    5. WaitformultibleObjectsEx kehrt zurück ReadEvent gesetzt
    6. Daten werden geparsed und Es wird ein StatusChanged Event gesetzt (für sich selber)
    7. thread geht über returns wieder in WaitformultibleObjectsEx
    8. nach 450-650 ms kehrt WaitformultibleObjectsEx mit dem Statusevent zurück
    9. and device 2 wird Start gesendet

    Dieser ablauf ist unter XP derselbe nur das das WaitformultibleObjectsEx an Position 8 schon nach 50-150 ms zurückkehrt. Was könnte das Problem verursachen.

    MfG



  • 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


Log in to reply