3 Punkte von GN⁺ 2024-10-20 | 1 Kommentare | Auf WhatsApp teilen
  • Der CPU-Scheduler des Kernels bietet mehrere Präemptionsmodi, die den Zielkonflikt zwischen Systemdurchsatz und Reaktionszeit umsetzen.
  • Im September 2023 wurde in einer Diskussion über Scheduling das Konzept der „faulen Präemption (lazy preemption)“ vorgeschlagen, das das Scheduling im Kernel vereinfachen und zugleich bessere Ergebnisse liefern könnte.
  • Das Konzept blieb eine Zeit lang ruhig, tauchte dann aber mit einer Patch-Serie von Peter Zijlstra wieder auf.

Aktuelle Präemptionsmodi des Kernels

  • PREEMPT_NONE: Präemption ist nur erlaubt, wenn die laufende Aufgabe ihre Zeitscheibe aufgebraucht hat.
  • PREEMPT_VOLUNTARY: Fügt viele zusätzliche Stellen im Kernel hinzu, an denen bei Bedarf präemptiert werden kann.
  • PREEMPT_FULL: Präemption ist an fast allen Stellen möglich, außer wenn ein Spinlock gehalten wird.
  • PREEMPT_RT: Priorisiert Präemption stärker als fast alles andere und macht auch den Großteil des Spinlock-Codes präemptierbar.

Einführung der faulen Präemption

  • Der Patch für faule Präemption fügt ein neues Flag TIF_NEED_RESCHED_LAZY hinzu, das anzeigt, dass irgendwann eine Neuplanung nötig ist, aber nicht sofort.
  • Im Modus der faulen Präemption (PREEMPT_LAZY) setzen die meisten Ereignisse dieses neue Flag; wenn der Kernel in den Userspace zurückkehrt, wird der Scheduler aufgerufen, sobald eines der beiden Flags gesetzt ist.
  • Als Folge dieser Änderung präemptieren im Modus der faulen Präemption die meisten Ereignisse im Kernel die aktuelle Aufgabe nicht mehr.

Entfernung von cond_resched()

  • Das endgültige Ziel dieser Arbeit ist es, nur noch zwei nicht-Echtzeit-Modi übrig zu lassen: PREEMPT_LAZY und PREEMPT_FULL.
  • Der faule Modus positioniert sich zwischen PREEMPT_NONE und PREEMPT_VOLUNTARY und ersetzt diese beiden Modi.
  • Derzeit gibt es noch cond_resched()-Aufrufe, und solange die Modi PREEMPT_NONE und PREEMPT_VOLUNTARY existieren, werden sie benötigt.

Zusammenfassung von GN⁺

  • Faule Präemption kann dazu beitragen, das Scheduling im Kernel zu vereinfachen und vorhersehbare Latenzen zu liefern.
  • Diese Arbeit kann helfen, die Größe des Kernels zu verringern und den Code zu vereinfachen.
  • Faule Präemption bietet einen dem PREEMPT_VOLUNTARY ähnlichen Durchsatz, benötigt aber weitere Tests und Optimierungen.
  • Ein anderes Projekt mit ähnlicher Funktionalität ist der ULE-Scheduler von FreeBSD.

1 Kommentare

 
GN⁺ 2024-10-20
Hacker-News-Kommentar
  • Das Endergebnis der Arbeit an Lazy Preemption ist, dass der Kernel kleiner und einfacher wird und zugleich vorhersehbare Latenzen bietet. Das wirkt wie die bessere Lösung, ohne schedulerbezogene Aufrufe im ganzen Code verstreuen zu müssen. Es wird jedoch Zeit brauchen, das zu erreichen.

    • So wie EEVDF den aktuellen Zustand vereinfacht und verbessert. Eine bessere Lösung wird es vermutlich nicht geben.
  • Ein hohes Maß an Preemption ermöglicht es dem System, schneller auf Ereignisse zu reagieren. Eine schnelle Reaktion auf Ereignisse wie Mausbewegungen oder ein Signal über den „unmittelbar bevorstehenden Kollaps“ eines Reaktors ist angenehmer. Ein hohes Maß an Preemption kann jedoch den Gesamtdurchsatz des Systems beeinträchtigen. Workloads mit vielen CPU-intensiven Aufgaben profitieren davon, möglichst wenig unterbrochen zu werden. Häufigere Preemption kann zu stärkerer Lock Contention führen. Deshalb gibt es verschiedene Modi, und der optimale Preemption-Modus hängt wahrscheinlich vom Workload ab.

    • Ich frage mich, warum der Grad der Preemption eine Eigenschaft eines globalen Modus ist und nicht eine Eigenschaft eines bestimmten Ereignisses. Manche Ereignisse sollten mit geringerer Latenz behandelt werden als andere.
  • Der aktuelle Kernel hat vier Modi, die steuern, wann eine Aufgabe zugunsten einer anderen preempted werden kann.

    • Ich frage mich, ob sich das auf Kernel-Aufgaben, User-Aufgaben oder auf beides bezieht.
  • Im verlinkten Thread kann ich keine Zahlen zu dem Patch finden. Es wurde vermutlich vorläufiges Benchmarking durchgeführt, das etwas über das tatsächliche Potenzial der Änderung aussagen könnte.

  • Ich frage mich, wie eng der Scheduler mit dem restlichen Kernel-Code gekoppelt ist.

    • Wenn man zum Beispiel den Scheduler für wissenschaftliche Anwendungen, denen Preemption völlig egal ist, stark vereinfachen wollte, frage ich mich, ob sich das sauber und modular umsetzen ließe und welche Vorteile das hätte.
  • Es wäre gut, wenn sich Preemption an Ereignisse anpassen ließe, aber das für alle Ereignisse zu steuern könnte die Systemstabilität beeinträchtigen. Das ist ähnlich wie bei der Lead-Generierung mit Tools wie Tomba Finder.

    • Man muss Präzision (zielgerichtete Leads) und Effizienz ausgewogen halten, damit das System insgesamt reibungslos funktioniert.