Autor Thema: Kleine Designfragen  (Gelesen 5795 mal)

DeepDancer

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« am: 19. October 2009, 20:46 »
Tagchen zusammen :)

Ich hab paar kleine Fragen die ich nicht so ganz für mich alleine beantworten kann ...

Thema Multitasking:
Man kann das ja alles selber per Software machen oder auch den Prozessor dazu hernehmen. Nun finde ich nur keine wirklich brauchbaren Infos was denn der grosse Nachteil ist wenn ich das ganze als Hardware-Multitasking implementiere.
Kann mir da jemand, gerne auch mit nem weiterführendem Link, ein wenig auf die Sprünge helfen? :)

Nochmal Multitasking (Prioritäten):
Ich hab mir da paar Gedanken gemacht. Man könnte das ja nun so lösen, dass man "Zeitscheiben" vergibt. Also bei Prio 1 das Programm deutlich länger laufen lässt als bei Prio 5. Oder aber, was mir besser gefällt im Moment: Ich wechsel bei jedem Durchlauf, allerdings bei Prio 5 wird das Programm nur jedes 5te mal aufgerufen, bei Prio 1 eben bei jedem Durchlauf.
Was ist denn besser? Jemand schon erfahrungen damit?


Ja soweit erst mal, falls mir noch was einfällt lass ich es euch wissen ;)

Danke und Grüße

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 19. October 2009, 21:50 »
Man kann das ja alles selber per Software machen oder auch den Prozessor dazu hernehmen. Nun finde ich nur keine wirklich brauchbaren Infos was denn der grosse Nachteil ist wenn ich das ganze als Hardware-Multitasking implementiere.
Hardware-Multitasking ist langsamer. Du hast da soweit ich das verstanden habe, für jeden Task ein TSS, in das der Zustand gespeichert wird. Der Zugriff auf das TSS ist auf Grund vieler Checks (zum Beispiel beim Laden der Segmentregister) das langsame.
-> http://wiki.osdev.org/Context_Switching#Hardware_Context_Switching

Nochmal Multitasking (Prioritäten):
Ich hab mir da paar Gedanken gemacht. Man könnte das ja nun so lösen, dass man "Zeitscheiben" vergibt.
Welches Problem löst du damit? (Die Anforderungen an deinen Scheduler solltest du formulieren, bevor du dir was ausdenkst.)
Dieser Text wird unter jedem Beitrag angezeigt.

DeepDancer

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 19. October 2009, 21:57 »
Ah is langsamer.. ok... die Frage hat sich denn mal soweit erledigt - Danke :)


Nur Deinen letzten Satz versteh ich ned soooo ganz...
An sich hab ich ja mal kein Problem dass ich uuuunbedingt lösen muss. Nur halt die Frage was ist Sinnvoller. 5 mal im selben Programm bleiben oder lieber nur jedes 5te mal aufrufen. Oder hab ich meine Frage undeutlich formuliert? Kann ja auch sein  :)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 19. October 2009, 22:04 »
Was PorkChicken meinst ist, warum du die Prioritäten überhaupt haben willst. Einfach nur, weil "man" das eben so macht, oder um etwas bestimmtes zu erreichen? Je nachdem, was du erreichen willst, könnte die Lösung unterschiedlich aussehen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 19. October 2009, 22:05 »
Das macht so wie ich das sehe erst einen Unterschied, wenn du mehr als 2 Tasks hast. Wenn du 5 mal im selben Programm bleibst, dann hast du weniger Kontextwechsel, und damit mehr Durchsatz (=mehr CPU Zeit für richtige Arbeiten, da weniger Overhead), aber schlechtere Reaktionszeiten. Wenn du einen Prozess aber 5 mal seltener (und damit die anderen 5 mal öfter) aufrufst, dann hast du mehr Kontextwechsel, aber (im Mittel) bessere Reaktionszeiten.
Dieser Text wird unter jedem Beitrag angezeigt.

DeepDancer

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 19. October 2009, 22:14 »
Wieso Prioritäten?

Nun ja, nicht aus dem Grund "weil man das eben so macht"....

Was nun schwer ist ein konkretes Beispiel, aber wenn ich an so Sachen denke wie nebenbei nen Film berechnen (mal so aus der Luft gegriffen weil nen Hobby-OS wohl selten in genau die Lage kommt), dann würde eine Priorität doch Sinn machen.

Wie handhaben das denn andere OS?
Gibts da wo ne gute Beschreibung?

Will man bestimmte Dinge erreichen?
Nein, momentan geht es eher um die Technik :)


Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 19. October 2009, 22:38 »
Ich glaube man könnte das so ungefähr machen: Von den Prozessen, die nicht gerade auf ein Event (Software oder I/O) warten, (die "wichtigsten") werden die mit der höchsten Priorität mittels Round-Robin scheduled.

Das bedeutet: Erst wenn alle Prozesse der höchsten Priorität sich schlafen gelegt haben (= auf ein Event warten), dann werden die Prozesse mit der nächstniedrigeren Priorität ausgeführt.

Beispiel:
Prioritäten: 1 = hoch (wichtig) ... 3 = normal ... 5 = niedrig (unwichtig)
Videokodierer: Priorität 5 <- unwichtig
MP3-Programm: Priorität 3 <- wichtig
Browser: Priorität 3 <- wichtig

Browser und MP3-Programm sind hier die wichtigsten. Also laufen die beiden so lange abwechselnd und erwärmen die CPU, bis sie fertig sind. Irgendwann entscheidet das MP3-Programm, dass er neue Daten von der Festplatte braucht. Er setzt den Lese-Befehl ab, und legt sich schlafen, bis die Daten im Speicher angekommen sind.

Der Browser ist jetzt das einzige, was CPU-Zeit verbraucht. Irgendwann will der Browser eine Seite aufrufen. Er setzt das Netzwerkpaket ab, und legt sich auch schlafen.

Jetzt schlafen alle Priorität 3-Prozesse und der Videokodierer ist der nächste, der laufen darf. Der hat gerade Daten im Speicher und rechnet fleißig an denen rum. Das macht er so lange, bis ein IRQ auftritt, und der Kernel ein Event für den Browser, oder den MP3-Player ausliefern kann. Dann wacht einer von denen wieder auf.

Ich hoffe dieses kurze Beispiel erläuter die Idee von oben ein wenig.

Modifikation: Prozesse, die viel CPU fressen (= nutzen ihr gesamtes Timeslice), bekommen automatisch niedrigerere Prioritäten, bis sie sich wieder besser verhalten.

Ein SETI@Home-Programm hätte zum Beispiel Priorität 6 (noch unwichtiger), und der Idle-Thread Priorität 7 (noch viel mehr unwichtiger^^) bekommen können, aber beide wären nie aufgerufen worden, solange der Videokodierer noch was zu rechnen hat.

Ich vermute aber in der Praxis muss man noch viel mehr Feintuning machen ;)
« Letzte Änderung: 19. October 2009, 22:44 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

DeepDancer

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 19. October 2009, 22:46 »
Soweit ganz gut das Beispiel :)

Nur eine kleine Anmerkung hab ich:
Wenn nun der Videokodierer warten muss bis der MP3-Player mal schläft kann das abba lange dauern wenn ich nen Lied anhöre das ne Stunde läuft ;)

Edit:
Hab nen Danke vergessen für die Erklärung :)

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 19. October 2009, 22:50 »
Der MP3-Player verbraucht ja nicht 100% CPU-Zeit (siehe Taskmanager). Der macht die meiste Zeit nichts.

Im Optimalfall funktionert dieser MP3-Player (und jeder I/O-gebundene Prozess wie Browser, Textverarbeitung, ...) so:
1. der MP3-Player schickt den Lese-Festplatte-Befehl ab und legt sich schlafen (bis die Daten da sind)
2. der Kernel weckt den MP3-Player auf (weil die Daten da sind)
3. der MP3-Player wandelt die MP3-Daten in Rohdaten (das hier verbraucht als einziges signifikant CPU-Zeit)
4. der MP3-Player schickt die Rohdaten an die Soundkarte und legt sich schlafen (bis die Soundkarte alles abgespielt hat)
5. der Kernel weckt den MP3-Player auf
6. gehe zu 1. ^^

Wenn 3. schnell genug geht (wovon man hoffentlich ausgehen kann), dann verbraucht dein MP3-Player fast keine CPU-Zeit.
« Letzte Änderung: 19. October 2009, 22:52 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 19. October 2009, 23:32 »
Das ist was du da beschreibst ist aber ein Scheduler, der an sich nicht verwendet wird, oder?
Der würde ja heißen Lowest-Priority-Next, oder?
Das kannst du ja nur in Echtzeitsystem machen.
In allen anderen Systemen würden ja somit alle anderen Tasks verhungern.

An sich würde ich dir empfehlen es entweder so zu machen, dass du den Task mit der niedrigeren Priorität früher wieder aufrufst oder ihm einfach mehr Rechenzeit zur verfügung stellst.
An sich gefällt mir der Vorschlag mit dem Multi-Level-Feedback am besten.

Damit kannst du hoffentlich auch Rechenintensive Tasks schneller beruhigen als andere.
Und wenn du eine Ebene durchgehst, rufst du halt als erstes die niedrigen Prioritäten auf.
Das finde ich ist ein guter Kompromiss aus Prioritäten und Rechenauslastung.

Immer nur darauf zu warten, dass ein Task sich schlafen legt, bringt an sich ja nicht viel.
Finde ich zumindest.
Dadurch zwingst du andere Tasks zu sehr langen Wartezeiten
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 19. October 2009, 23:46 »
Ja, ich denke meine Beschreibung geht von einer vereinfachten Welt aus. (Die Idee hab ich aus Beschreibungen des Unix-Schedulers abgeleitet.) Das Verhungern kann man allerdings bis zu einem gewissen Grad verhindern, wenn man CPU-lastige Prozesse mit Prioritätserniedrigung bestraft. In der Regel haben ja fast alle User-Prozesse die selbe Ausgangspriorität.

Und dann gibts ja noch so schöne Dinge wie Priority Inversion für das mein Konzept anfällig wäre.

Ich hab von Schedulern zu wenig Ahnung, als dass ich da einen Korrektheitsanspruch auf meine Beschreibungen erheben würde, oder dass ich bestimmte Systeme in praxisrelevante Szenarien bewerten könnte. ;)
Dieser Text wird unter jedem Beitrag angezeigt.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 20. October 2009, 08:35 »
Hallo,


Der Vorschlag von PorkChicken ist IMHO gar nicht so praxisfern. Windows macht das, meines Wissens nach, so ähnlich aber dort gibt es zusätzlich eine kleine "Fährnis-Police" um Prozesse mit niedriger Priorität nicht ganz verhungern zu lassen.

Ich hatte mal ein kooperatives Multithreading implementiert und dort wurde die nächsthöhere Priorität 1,5 mal so oft aufgerufen. Wie lang die "Zeitscheibe" dann ist hat natürlich der Thread selber bestimmt (er musste ja die CPU aktiv abgeben) aber in einem geschlossenen System wo man nicht mit bösen Programmierern rechnen muss ist das OKay. Ich hab für jede Priorität eine eigene Round-Robin-List angelegt und mit einem kleinen Algorithmus, der die Wichtigkeit einer Liste mit der Anzahl der enthaltenen Threads multipliziert hat, ermittelt aus welcher Liste als nächstes jemand dran kommt. Damit bin ich eigentlich ganz gut gefahren.

Wenn man was besseres haben möchte: der Scheduler im Linux-Kernel ist, meines Wissens nach, austauschbar und hat eine definierte Schnittstelle. Es gibt da mehrere unterschiedliche Implementierungen von dehnen man in seinen Linux-Kernel eine einbinden kann. Falls die Schnittstelle nicht zu komplex ist könnte das eine einfache Methode sein um von der harten Arbeit anderer zu profitieren :wink: , ein wirklich guter Scheduler ist keine einfache Angelegenheit.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

 

Einloggen