Linux 6.14: Bessere Performance, aber verschlafener Release-Termin | heise online

Linux 6.14: Bessere Performance, aber verschlafener Release-Termin

Der Kernel Linux 6.14 verspricht Performance-Steigerungen bei Windows-Apps unter Wine und beim direkten I/O. Er erschien durch Vergesslichkeit einen Tag später.

vorlesen Druckansicht 110 Kommentare lesen
Pinguin sitzt vor Computer und programmiert

(Bild: Erstellt mit KI in Bing Designer durch heise online / dmk)

Lesezeit: 11 Min.
Von
  • Oliver Müller
Inhaltsverzeichnis
close notice

This article is also available in English. It was translated with technical assistance and editorially reviewed before publication.

Der neue Linux-Kernel 6.14 erblickte am Montagabend unserer Zeit das Licht der Welt. Damit erschien der Kernel-Neuling einen Tag später als üblich. Zwar gab es auf den letzten Metern ein paar Patches, die für Knirschen in der Build-Maschinerie der Kernel-Entwickler sorgten. Der Kern der Verzögerung war aber rein menschlich: Linus Torvalds hatte schlicht vergessen, den Kernel freizugeben. Das gab der Linux-Vater in seiner Release-Meldung unumwunden zu.

Der Kernel-Frischling bringt unter der Haube einige innovative Ideen unter. Die Neuerungen stehen im Zeichen der Leistungssteigerung.

Sollen mehrere Threads auf eine gemeinsame Ressource verändernd zugreifen, braucht es eine Steuerung für die nebenläufigen, konkurrierenden Gesellen. Um den gleichzeitigen Zugriff auf die Ressource durch mehrere Theads zu verhindern, kommt ein Mutex zum Einsatz. Dieser sperrt (lock) die Ressource, wenn ein Thread auf diese zugreift. Alle anderen Threads, die ebenfalls die Ressource anfordern, werden so lange blockiert, bis der ursprüngliche Thread die Sperre aufhebt.

Linux verfügt mit "Fast Userspace Mutex" (Futex) über einen effizienten und flexiblen Mechanismus zur Synchronisation von Threads. Er kombiniert hierzu geschickt beim Verwalten der Mutexe Userspace und Kernelspace. Statt den Kernel generell mit der Sorge um den Mutex zu betrauen, bleibt die Verwaltung des Mutex im Userspace. Zum Anfordern eines Mutex braucht es keine Kernel-Rechte. Das Delegieren in den Kernelspace samt teurem Kontextwechsel ist nur dann notwendig, wenn Threads zu "parken" (sleep) oder "aufzuwecken" (wake) sind. Nämlich dann, wenn der Mutex bereits gesperrt ist oder wieder frei wird.

Innerhalb von Linux funktioniert dieser Mechanismus hervorragend, schnell und effizient. Probleme kommen auf, wenn andere Welten einzubinden sind. Das ist beispielsweise beim Nachbau von Windows in der Kompatibilitätsschicht Wine der Fall. Die meisten Windows-Sperren lassen sich auf Futex abbilden. Der Locking-Bauchladen von Windows funktioniert intern anders, sodass einiges nicht ohne Scheuern und Wetzen sowie Kopfzerbrechen möglich ist.

Videos by heise

Die Liste der Abbildungsschwierigkeiten ist lang. Schwer abzubilden ist beispielsweise das Anfordern mehrerer Sperren in einem Schritt. Auch die speziellen Sperren in Form von Events (Ereignisse) von Windows harmonieren nicht mit dem Futex-Konzept. Das Event ist eine Bedingungsvariable in Form eines booleschen Werts. Als Sperrwert hat das Event "falsch" (false). Die Threads warten, bis die Variable den Wert "wahr" (true) annimmt. Soweit wäre das auch mit Futex problemlos lösbar. Der Teufel steckt jedoch wie so oft im Detail.

Es gibt zwei Typen von Events. Sie können selbst rücksetzend (auto-reset) sein. Sowie ein Thread in der Warteschlange zum Zuge kommt, wechselt der Wert zurück auf false. Die anderen Threads sehen dieses Ereignis überhaupt nicht. Ist das Event nicht als "auto-reset" gekennzeichnet, setzt sich der Wert nicht zurück, sondern verharrt auf true. Der Wert muss explizit wieder auf false zum Sperren gesetzt werden. Das sehen alle wartenden Threads.

Um dem Herr zu werden, hat die Entwicklerin Elizabeth Figura eine Reihe von Patches beigesteuert. Linux 6.14 bringt einen neuen Treiber zur NT-Synchronisation mit. Er findet sich als /dev/ntsync im virtuellen Dateisystem wieder. Alle Synchronisationsmechanismen von Windows sind darin ausgelagert, die mit Futex nicht mehr oder weniger eins zu eins realisiert werden können. Die Dokumentation zu ntsync findet sich bei docs.kernel.org.

Der ganze Aufwand hat ein konkretes Ziel. Auf Wine aufsetzende Windows-Programme können bislang massiv ausgebremst werden. Hängt ein Auto-Reset-Event beispielsweise auf mehrere gleichzeitig angeforderten Ressourcen, wird's haarig.

In Windows können die mehreren gleichzeitig angeforderten Ressourcen in einem Zug und damit atomar gesperrt werden. Dabei kann die Zusammenstellung der Ressourcen zur Laufzeit variieren. Ein Futex kann das nicht adäquat abbilden. Vielmehr bekäme ein wartender Thread einzelne Ressourcen aus der Gruppe, wenn diese frei werden. Sind es nicht alle Ressourcen, geht dieser wieder in den wartenden Schlaf. Wird die nächste Ressource aus dem Bündel frei, heißt das nicht zwingend, dass diese an den gleichen Thread geht. Je nach Implementierung können die Konsequenzen von ruckelnden Anwendungen bis zum Einfrieren der Windows-App reichen.

Der neue Ansatz soll das vermeiden und stellt einen Geschwindigkeitsgewinn in Aussicht. Dabei werden vor allem grafiklastige Apps und vor allem Windows-Spiele profitieren. Da nicht alle Windows-Anwendungen gleichermaßen von dieser speziellen Art der Synchronisation betroffen sind, liegt die Prognose für die Geschwindigkeitssteigerung in einem breiten Bereich. Bei der Frame-Rate von Spielen soll sich die Steigerung zwischen 50 und 150 Prozent bewegen.

Bislang gab es in Linux zwei Hauptarten von Datei-I/O. Entweder gepuffert (buffered) oder direkt. Das Standardverhalten ist Buffered I/O, das Daten über den Page-Cache liest und schreibt. Der Vorteil ist der schnelle Zugriff beim wiederholten Lesen. Die Daten liegen im Page-Cache und müssen nicht erneut teuer vom Massenspeicher geholt werden. Diesen Vorteil erkauft sich Buffered I/O durch das Problem aller Caches.

Der Page Cache kann inkonsistent sein, also nicht mehr mit dem Inhalt auf dem Speichermedium übereinstimmen. Das ist dann der Fall, wenn andere Systemteile dieselben Daten verändern, aber den Cache umgehen. Das gute alte Direct Memory Access (DMA) und Direct I/O sind prominente Beispiele, die Buffered I/O in die Quere kommen können.

Das Direct I/O umgeht den Page-Cache vollständig und greift immer direkt auf den Massenspeicher zu. Die Daten via Direct I/O spiegeln immer den aktuellen Stand auf dem Speichermedium wider. Nachteilig ist dafür der teils langsamere Zugriff auf die Daten. Insbesondere bei mehreren kleinen Zugriffen, da keine Daten über eine Blockgröße auf Vorrat gelesen oder geschieben werden. Im Gegensatz kann das Buffered I/O Daten mit der optimalen Blockgröße schreiben und lesen. Der Cache machts möglich.

Linux 6.14 vereint die beiden gegensätzlichen Ansätze in einem Mittelweg. Zunächst klingt das neue "Uncached Buffered I/O" widersprüchlich: nicht gepufferte, aber dennoch gepufferte Zugriffe. Schließlich ist ein Cache auch nur ein Puffer.

Der Trick besteht darin, den Page-Cache wie beim Buffered I/O zu verwenden. Allerdings werden die zwischengespeicherten Daten nicht wiederverwendet. Die verwendeten Pages werden verworfen und nicht als "clean" fürs erneute Verwenden markiert. Jeder Zugriff holt die Daten neu vom Speichergerät. Kurz gesagt: "Verhalte dich wie Buffered I/O, aber tue so, als wäre der Page-Cache leer."

Dadurch ist Uncached Buffered I/O flexibler und effizienter bei kleinen Zugriffen als Direct I/O. Die normale Blockgröße beim Zugriff erlaubt optimiertes Lesen vom Speichergerät. Das Invalidieren von Caches entfällt, wie es sonst beim Zusammenführen der beiden Ansätze notwendig wäre. Der Ansatz ist schlank und einfach im Kernel zu implementieren. Von einer besseren Performanz profitieren Anwendungen, die selbst "cachen" oder Daten mehrfach verändern.

Buffered I/O ist die beste Wahl für normale Programme. Direct I/O ist die Domäne von Datenbanken und des High-Performance Computing (HPC), die Daten selbst verwalten, cachen und nah an der Hardware sitzen wollen. Das neue Uncached Buffered I/O schließt die Lücke für Hochleistungsanwendungen, die zwar effizient gepuffert lesen wollen, aber auf die Konsistenz der Daten angewiesen sind.

Auf der GPU ablaufende Prozesse möchte man ungern abbrechen. Schließlich sollen die rechenintensiven Aufgaben nicht erneut angestoßen werden müssen. Der neue Kernel sagt dem Zwangsrauswurf über cgroups den Kampf an. Sowohl die Ressourcen der GPU, als auch von Treibern allokierter CPU-Speicher splittet Linux nun in cgroups auf. Das erlaubt das parallele Ausführen von Aufgaben, ohne sich gegenseitig zu beeinflussen.

Mit dem Vorgänger 6.13 führte Linux das "Lazy Preempt" ein. Es gestattet im präemptiven Multitasking, Kontextwechsel aufzuschieben, um Prozesse beziehungsweise Threads nicht unnötig zu unterbrechen. Auf diese Weise sollen Verarbeitungsschritte möglichst in einem Zug abgeschlossen werden können. Dieses "Lazy Preempt" war in Linux 6.13 nur auf Rechnern mit CPUs vom Typ x86/x86_64 und RISC-V verfügbar. Jetzt zieht der Kernel-Neuling für die nächste Architektur nach. Mit Linux 6.14 steht das "Lazy Preempt" auch für Systeme mit PowerPC bereit.

Das Dateisystem btrfs führt fürs Read Balancing bei RAID1 (Spiegelung, Mirror) drei neue Strategien ein. "Rotation" hält alle Geräte des Spiegels aktiv und ist die Voreinstellung. "Latency" rückt fehleranfälligen und unstabilen Block-Layern intelligent zu Leibe. "devid" schließlich erlaubt die manuelle Kontrolle. Je nach Anwendungsszenario soll die passende Strategie helfen, Lesezugriffe über die Geräte im RAID1 besser zu verteilen.

XFS bohrt sein Realtime-Device auf. Dieser Spezialmodus ermöglicht konsistente, vorhersagbare Latenzen für Dateisystemoperationen. Im neuen Linux-Kernel kommt das "reverse mapping" hinzu. Es gestattet, Blöcke auf dem Speichergerät der Datei zuzuordnen, von der die Speicherblöcke verwendet werden. Normaleweise lassen sich nur von der Datei ausgehend die zugehörigen Blöcke identifieren. Ebenfalls neu ist "reflink". Damit können Dateien in XFS Speicherblöcke gemeinsam nutzen. Das vermeidet Redunanz und spart Speicherplatz.

Microsoft hatte PC-Tastaturen eine neue Taste spendiert. Die Copilot-Taste dient zum Zugriff auf den KI-Assistenten des Software-Riesen aus Redmond. Bislang ignorierte Linux diese Taste. Jetzt erkennt Linux auch, wenn diese Taste gedrückt wird. Allerdings verbindet das keine feste Verknüpfung mit dem Copilot-Assistenten.

Mit etwas über 11.000 Changesets mit neuer Funktionalität bleibt Linux 6.14 bescheiden hinter einer langen Reihe seiner Ahnen zurück. Nur Linux-Kernel der Versionen 4.x waren diesbezüglich kleiner. Trotz dieser "mageren" Quantität bringt der Neue vieles an Qualität mit. Die Geschwindigkeitssteigerungen bei Windows-Games sind beachtlich. Der geniale Trick beim Uncached Buffered I/O schließt eine Lücke zwischen den sonst gegensätzlichen I/O-Strategieren. Allein dies macht die nächste Inkarnation des Kernels zum Innovationsschub.

Der Linux-Kernel 6.14 steht wie gewohnt auf kernel.org zum Download bereit. Alle Neuerungen und Änderungen fasst das Changelog zusammen. Eine strukturierte Übersicht der Änderungen gegenüber dem Vorgänger 6.13 findet sich zudem im git-Repository.

(dmk)