Thread Sheduling Änderungen von Windows XP nach Windows 7



  • 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 😉



  • Entschuldigung, dass ich hier so reinplatze... ich versuche mich gerade in das Threading reinzuwursteln und lese hier von Jochens Ansatz...
    Verstehe ich das richtig, dass du mit den Fibers sozusagen Threadpools umsetzt, wobei in jedem Pool kooperatives scheduling betrieben wird? Irgendwie verstehe ich das gerade nur so diffus, weil ich mir nicht genau erklären kann, was nun der Vorteil oder besser Unterschied gegenüber der "sequentiellen" Abarbeitung von Tasks in solch einem Thread ist. Schließlich muss ein Fiber ja explizit ein anderes Fiber aktivieren, wenn der Wechsel stattfinden soll, zumindest wenn ich die Doku richtig lese. Das heißt, ich meine zu verstehen, dass Fibers sich nicht "schlafen legen" können, während sie auf ein Event warten und dann automatisch wieder geweckt werden, sollte das Event eintreten (sie sind ja nicht mehr "aktuell", sobald auf ein anderes Fiber geswitcht wird).
    Hast du eventuell etwas Zeit, um das System etwas genauer zu erläutern? Würde mich sehr freuen mal von solch praktikablen Ansätzen zu lesen.

    Viele Grüße,
    Deci



  • Das System ist ein komplettes "Tasking-System" welches auch eigene Methode für alle möglichen Dinge hat:
    - Sleep
    - Semaphore
    - MsgQueues
    - usw.
    Eben alles, was man so von einen Task erwartet.

    Der größter Vorteil ist, dass man sich *nicht* um das synchronieren von Threads kümmern muss (wenn man nur einen User-Mode-Thread hat). Damit betreiben wir Anlagen mit ca. 4000 I/Os und 20 seriellen Schnittstellen in Echtzeit.
    Man muss nur einige Dinge beachte (keine Zugriffe auf Dateisystem usw.) um hier relativ sicher zu sein. Das System erlaubt auch das zeitweise "ausbrechen" aus dem Fiber-Verbund und dann ein ausführen als "normaler" Thread, welches dann wieder alles erlaubt.



  • So ich habe jetzt nochmal neue Informationen.

    Wenn ich das Programm auf einen Core force funktioniert es schnell genug.

    Jetzt verstehe ich das nicht. Ich habe n Threads die ich auf m Processor Cores verteile. Wenn m>1 ist läuft das Programm zu langsam. Wonach sollte man schauen?

    MfG



  • @jochen:

    gibts zu dem fiber - thema noch mehr informationen als die eher allgemein gehaltenen in der msdn? hört sich sehr intressant an!

    was mich da auch intressieren würde ist (bitte korrigieren falls ichs falsch verstehe) folgendes:
    die synchronisation zwischen den threads wird ja dadurch unnötig da man mit den fibers im selben prozessraum arbeitet. wenn jetzt mehrere io - schnittstellen daten liefern müssen die ja auch irgendwo hin... und spätestens beim zusammenführen der daten muss doch dann auch wieder irgendwie synchronisiert werden? verlagert sich das problem dadurch nicht nur?

    sorry fürs offtopic werden.



  • Ja, es gibt auch Methoden mit denen man asynchorn Messages oder Semaphore signalisieren kann. Dadurch kommt man auch von "außen" in das System rein...
    Das ganze wurde aber um das Fiber-Konzept drum-rum programmiert und ist nicht ganz trivial...
    WIr sollten entweder in "RUDP" oder "Projekte" weiterdiskutieren..



  • Hallo Leute,

    dürfte ich euch bitten zum Problem zurückzukehren:

    Wenn ich das Programm auf einen Core force funktioniert es schnell genug.

    Jetzt verstehe ich das nicht. Ich habe n Threads die ich auf m Processor Cores verteile. Wenn m>1 ist läuft das Programm zu langsam. Wonach sollte man schauen?

    MfG



  • Nun, damit ist es ziemlich eindeutig, dass der Synchronisationsoverhead in deinem Programm größer ist als der Nutzen durch die Parallelisierung. Vermutlich ließ der Windows XP Scheduler das Ding einfach sowieso großteils auf einem Core laufen, sodass es dort nicht auffiel. Was du machen kannst: Reduzier den Sync Overhead. Möglicherweise ist das Problem einfach nicht parallelisierbar? Dann verwend weniger Threads.


Anmelden zum Antworten