Hallo,
Wichtig ist es, möglichst lange den einzelnen Prozess auf einer CPU ausführen zu lassen, wenn du ständig die CPUs wechselst, verlierst du die Cache-Inhalte.
Ich würde jetzt erstmal wissen wollen, was du unter einem Prozess verstehst.
Auch Tasks. Oder auch Threads, genaueres ist Definitionsfrage.
Nur bin ich noch von dem einen Prozess auf einer CPU "festpinnen" nicht so richtig überzeugt. Ich wüsste jetzt spontan nicht mal wofür das gut sein sollte.
Damit kannst du ein vorhersehbareres Zeitverhalten fördern oder Prozesse, die sehr stark cachelastig sind und sonst ständig die CPU wechseln würden, daran hindern. Außerdem, wenn du zwei stark CPU-lastige Prozesse am Laufen hast und die auf je eine CPU festpinnst, hast du eine bessere (gleichmäßigere) Grundauslastung. Nennt sich unter Linux CPU-Affinität.
Wenn du einen Core frei von den üblichen Anwendungen (außer einer zeitkritischen) hast, dann bekommst du Near-Realtime allein im Userspace.
Damit kannst du neu entstehende Prozesse der CPU zuteilen, die gerade frei ist, und wenn eine CPU frei geworden ist, holst du dir aus dem Aufgabenpool den nächsten Prozess. Wenn ein Prozess blockt, wird er in den gemeinsamen Pool geschoben, wenn er seine Zeitscheibe aufgebraucht hat, landet er wieder in der CPU-eigenen Queue.
Klingt erstmal nicht schlecht, aber dadurch könnte es auch passieren das eine CPU 2 Threads hat und ne andere gar keine, weil die 2 Threads immer ihre Zeitscheibe aufbrauchen.
Wenn eine CPU wartet und die andere CPU noch Aufgaben zu erledigen hat, kann man die ja verschieben. Man weist also einer CPU ihre Prozesse zu und wenn sich die Aufteilung als schlecht erweist, wird nachträglich geändert. Das sollte auch recht sinnvoll skalieren.
In dem Moment wär es also besser wenn einer der beiden Threads in die globale Queue geschoben wird und dann die CPU die gar keine hat sich diesen nehmen kann.
Oder, dass sich die leerlaufende CPU bei anderen CPUs bedient. Wenn auf jeder CPU Prozesse laufen, die ihre Zeitscheibe aufbrauchen, dann passiert nichts, da der Scheduler ja über alle CPUs hinweg gleichzeitig die Zuteilung vornimmt.
Wo wir wieder bei meinem ein Queue System wären, was in dem Moment wahrscheinlich effektiver wäre. Genauso hast du da die selben Problem die ich auch schon mit nur einer Queue habe (das andere CPUs eventuell warten müssen bis sie auf die globale Queue zugreifen können).
Die globale Queue wäre für mich ein zentraler Aufgabenpool für Prozesse, die ihre Zeitscheibe nicht aufgebraucht haben - die damit also nur selten aufgerufen werden. CPUs, die ausgelastet sind, laufen also selbstständig ihre Prozesse ab und belasten die Hauptqueue nicht.
Eventuell sollte man den Scheduler mit einer gewissen Weitsicht ausstatten und selbst auf eine CPU festpinnen, so dass er die CPU-Zuteilung zentral regeln kann (und zwar so, dass er bereits die zukünftigen Zeitscheiben verteilt). Das benachteiligt interaktive Prozesse allerdings stark, so dass die Hauptqueue bevorzugt abgearbeitet werden muss; sie sollte aber die meiste Zeit leer oder sehr kurz sein (Prozesse, die ihre Zeitscheibe nicht aufbrauchen, brauchen meist die folgenden Zeitscheiben auch nicht).
Auf einem normalen System haben die meisten Prozesse die gleiche Priorität, und viele verschiedene Prioritäten gibt es auch nicht (mein Hostlinux: boinc* hat 39, der Kernel hat RT, udev 16 und der Rest 20 ==> 4 verschiedene). Die Prioritätsinversion kann damit nur selten auftreten.
soweit ich weiß hat Linux 256(??) Prioritäten (-127 bis 128). Auch verwendet er (wie ich) dynamische Prioritäten (war so als ich das letzte mal geguckt habe), wird also durchaus verschiedene Prios geben. Vorallem auf meinem OS (so wie es mir momentan vorschwebt) wird es unterschiedliche geben (im Bereich von 10 bis 20) und ich würde auch diesen "seltenen" Fall gerne vermeiden. Außerdem kann ich ja vorher nicht wissen was für Programme mit welchen Prios auf meinem System laufen.
Prioritätsinversion kannst du vermeiden, indem du beispielsweise für jeden Durchlauf der hohen Prioritätsqueue (mind.) einen Eintrag der niederen Priorität ausführst und so ein Verhungern vermeidest. Solange du aber keine tausende Prozesse auf deinem System laufenlassen möchtest, die alle verschiedene Prioritäten haben, bleibt es ein relativ seltenes Ereignis.
Es gibt Anwendungsfälle, die jeden Scheduler ineffizient machen. Bei nur zwei CPUs ist es sinnvoll, den Scheduler - auf Kosten des Durchsatzes - selbst zu verteilen, um eine bessere Auslastung zu bekommen. Bei sehr vielen CPUs ist es wieder sinnvoller, den Scheduler selbst auf eine CPU festzunageln, um den Durchsatz zu steigern. Der "wandernde" Scheduler führt dort zu größeren Verlusten.
Du merkst schon, ist ein schwieriges Thema für mich
Joa, aber ich möchte ja auch etwas bei lernen.
Gruß,
Svenska