Ich verstehe, dass Spinlocks im Linux-Kernel-Design echte Verschwendung sind.
Ich würde gerne wissen, warum Spin-Locks im Linux-Kernel-Design eine gute Wahl sind, anstatt etwas, das im Userland-Code häufiger vorkommt, wie Semaphor oder Mutex.
Ich verstehe, dass Spinlocks im Linux-Kernel-Design echte Verschwendung sind.
Ich würde gerne wissen, warum Spin-Locks im Linux-Kernel-Design eine gute Wahl sind, anstatt etwas, das im Userland-Code häufiger vorkommt, wie Semaphor oder Mutex.
Antworten:
Die Wahl zwischen einem Spinlock und einem anderen Konstrukt, das den Aufrufer veranlasst, die Kontrolle über eine CPU zu blockieren und aufzugeben, hängt in hohem Maße von der Zeit ab, die für die Durchführung eines Kontextwechsels erforderlich ist (Register / Status im Sperrthread speichern und Register / Status wiederherstellen) in einem anderen Thread). Der Zeitaufwand und auch die Cache-Kosten hierfür können erheblich sein.
Wenn ein Spinlock verwendet wird, um den Zugriff auf Hardwareregister oder ähnliches zu schützen, bei dem ein anderer Thread, auf den zugegriffen wird, nur wenige Millisekunden oder weniger benötigt, bevor er die Sperre aufhebt, ist es viel besser, die CPU-Zeit zum Spinnen des Wartens zu nutzen anstatt den Kontext zu wechseln und weiterzumachen.
Da die Frage impliziert, dass Spinlocks eine "Verschwendung" sind, sollten Spinlocks nur kurz gehalten werden.
Spinlocks sind nicht die einzige Möglichkeit, mehrere Threads zu synchronisieren. Mutexe / Semaphore werden ebenso im Linux-Kernel verwendet wie andere Synchronisationsprimitive (z. B. Warteschlangen, Ereignisse).
Der Kernel muss sich jedoch mit Fällen befassen, die der Benutzerbereich nie sieht. Ein häufiger Fall sind Interrupt-Handler. Interrupt-Handler können unter Linux nicht neu geplant werden, müssen jedoch häufig ein Synchronisationsprimitiv verwenden (z. B. um ein Arbeitselement zu einer verknüpften Liste hinzuzufügen, das von einem anderen Thread weiter verarbeitet wird). Da Interrupt-Handler nicht schlafen können, können sie keine Mutexe, Warteschlangen usw. verwenden. Dadurch bleiben so ziemlich Spinlocks übrig. Wenn ein Thread den Zugriff mit einem Interrupt-Handler synchronisieren muss, muss er auch denselben Spinlock verwenden.
Spinlocks sind nicht unbedingt eine Verschwendung. Sie sind für den Fall ohne Konflikte / Wartezeiten optimiert und können sehr schnell übernommen und freigegeben werden. In diesem Fall sind sie schneller und erfordern weniger Overhead als andere Synchronisationsprimitive.
Andere haben geantwortet. Ich werde die Fälle zusammenfassen, in denen Sie Spinlock verwenden würden, und Regeln, um Spinlock zu verwenden.
Antwort: In den folgenden Situationen.
Bei ordnungsgemäßer Verwendung kann Spinlock eine höhere Leistung als Semaphor liefern. Beispiel: Intrrrupt-Handler.
Ans:
Grund: Angenommen, Ihr Fahrer mit Spinlock geht in den Schlaf. Beispiel: Ruft die Funktion auf copy_from_user()
oder copy_to_user()
oder die Kernel-Preemption startet, sodass ein Prozess mit höherer Priorität Ihren Code beiseite schiebt. Effektiv gibt der Prozess die CPU frei, die den Spinlock hält.
Jetzt wissen wir nicht, wann der Code die Sperre aufheben wird. Wenn ein anderer Thread versucht, dieselbe Sperre zu erhalten, dreht er sich sehr lange. Im schlimmsten Fall würde dies zu einem Deedlock führen.
Der Kernel-Preemption-Fall wird vom Spinlock-Code selbst behandelt. Immer wenn der Kernel-Code einen Spinlock enthält, ist die Vorauszahlung auf dem entsprechenden Prozessor deaktiviert. Selbst ein Einprozessorsystem muss die Vorauszahlung auf diese Weise deaktivieren.
Grund: Unterstützen Sie Ihren Treiber dabei, einen Spinlock zu verwenden, der den Zugriff auf das Gerät steuert, und geben dann einen Interrupt aus. Dadurch wird der Interrupt-Handler ausgeführt. Jetzt benötigt der Interrupt-Handler auch die Sperre, um auf das Gerät zugreifen zu können. Wenn der Interrupt-Handler auf demselben Prozessor ausgeführt wird, beginnt er sich zu drehen. Der Treibercode kann auch nicht ausgeführt werden, um die Sperre aufzuheben. SO wird der Prozessor für immer drehen.
Grund: Lange Sperrzeiten verhindern auch, dass der aktuelle Prozessor geplant wird. Dies bedeutet, dass ein Prozess mit höherer Priorität möglicherweise warten muss, um die CPU zu erhalten.
Dies wirkt sich also auf die Kernel-Latenz aus (Zeit, die ein Prozess möglicherweise warten muss, um geplant zu werden). Normalerweise sollten Spinlocks für die Zeitdauer gehalten werden, weniger als die CPU benötigt, um einen Contex-Wechsel zwischen Threads durchzuführen.
Spinlocks und Mutexe werden aufgrund fehlender Ressourcen auf der CPU verwendet. Sie werden zu einem redundanten Erbe des 8-Bit-Register-basierten Von-Neumann-Designs. Dies ist die schlechteste Architektur, die heutzutage völlig unlogisch ist.
Leider sind die Funktionen des C / C ++ - Compilers in Bezug auf Funktionen, die mit den bis heute noch verfügbaren archaischen On-Chip-Ressourcen nicht in der Hardware eingeschlossen werden können, überproportional zur Hardware geworden. Caches sind daher in einem Uniprozessor einfach nicht über eine zweite Ebene hinaus wiedereintrittsfähig Der zeitaufwändige Kontext spart und viele neu eintretende SMPs werden fortgesetzt. Die Zukunft liegt bei FPGA-Geräten mit optimierten Build-Tools. Xilinix verfügt über einen neuen 14-nm-Prozess mit 3000 Verbindungen zwischen den A9-Quad-Cores und den programmierbaren Gate-Arrays, die halten Bis zu Hunderte von Megabits SRAM in Tabellen für fortschrittliches Zustandsmaschinendesign, das eine komplexe Float-Arithmetik / mehrdimensionale Vektor- / Eigentabellenreduzierung ermöglicht. So viel mehr als Ihr alter rollstuhlgebundener Compiler.
Mein Hardware-Design vor 25 Jahren hat erweiterte Hardware in eine DSP AD 21020 / CPU i960-Schnittstelle integriert. Es wurde klar, dass erweitertes Design viele Software-Probleme in diesem stromintensiven 160-Düsen-Drucker mit einer Breite von 1 Meter und 160 gelöst hat.
Personen, die mit der Kernel-Entwicklung vertraut sind, wurden eingeladen, ein kleines Team zu bilden, um eine neue Architektur zu evaluieren / zu modifizieren, die das Potenzial hat, Spinlocks / Cache-Misses / wiedereintretende SMP-Bedingungen zu ersetzen.