Ich weiß, dass Spinlocks mit Spining arbeiten, verschiedene Kernelpfade existieren und Kernel präemptiv sind, also warum Spinlocks in Einprozessorsystemen nicht funktionieren? (zum Beispiel in Linux)
Wenn ich Ihre Frage verstehe, fragen Sie sich, warum Spinlocks auf Einzelkernmaschinen eine schlechte Idee sind.
Sie sollten immer noch funktionieren , können aber sehr viel teurer sein als echte Parallelität beim Threading-Sleeping:
Wenn Sie einen Spinlock verwenden, behaupten Sie im Wesentlichen, dass Sie nicht denken, dass Sie lange warten müssen. Sie sagen, dass Sie denken, es ist besser, die Prozessor-Zeitscheibe mit einer ausgelasteten Schleife als die Kosten des Schlafes Ihres Threads und der Kontextverschiebung zu einem anderen Thread oder Prozess beizubehalten. Wenn Sie sehr kurze Zeit warten müssen, können Sie fast sofort schlafen und wieder erweckt werden, aber die Kosten für den Auf- und Abstieg sind teurer als nur warten.
Dies ist bei Multicore-Prozessoren wahrscheinlich in Ordnung, da sie viel bessere Nebenläufigkeitsprofile als Single-Core-Prozessoren haben. Bei Multi-Core-Prozessoren hat sich möglicherweise zwischen einigen Schleifeniterationen ein anderer Thread um Ihre Voraussetzungen gekümmert. Bei Single-Core-Prozessoren ist es nicht möglich, dass jemand anderes Ihnen geholfen hat - Sie haben den einzigen Kern abgeschlossen.
Das Problem hier ist, dass wenn du auf eine Sperre wartest oder schläfst, du dem System andeutest, dass du noch nicht alles hast, was du brauchst, damit es andere Sachen machen und später zu dir kommen kann Mit einer Drehsperre sagt man dies dem System nicht, also schließt man es ab und wartet auf etwas anderes - aber währenddessen hält man das ganze System hoch. , damit etwas anderes nicht passieren kann
Spinlocks haben die Eigenschaft, dass sie den Prozess nicht entplanen - stattdessen werden sie solange gedreht, bis der Prozess die Sperre erhält.
Auf einem Uniprozessor erwirbt er entweder sofort die Sperre oder er dreht sich für immer - wenn die Sperre umstritten ist, wird es niemals eine Gelegenheit für den Prozess geben, der die Ressource derzeit dazu bringt, sie aufzugeben. Spinlocks sind nur nützlich, wenn ein anderer Prozess ausgeführt werden kann, während sich einer auf der Sperre dreht - was Multiprozessorsysteme bedeutet.
Spinlocks sind von Natur aus für die Verwendung auf Multiprozessorsystemen gedacht, obwohl sich eine Einzelprozessor-Workstation, die einen präemptiven Kernel ausführt, hinsichtlich der Gleichzeitigkeit wie SMP verhält. Wenn ein nicht preemptives Einprozessorsystem jemals in eine Schleuse eindrang, würde es sich für immer drehen; Kein anderer Thread würde jemals in der Lage sein, die CPU zu erhalten, um die Sperre aufzuheben. Aus diesem Grund sind Spinlock-Operationen auf Einprozessorsystemen ohne aktivierte Voreinstellung optimiert, mit Ausnahme von denjenigen, die den IRQ-Maskierungsstatus ändern. Selbst wenn Sie niemals erwarten, dass Ihr Code auf einem SMP-System ausgeführt wird, müssen Sie aufgrund der Vorbelegung dennoch eine ordnungsgemäße Sperrung implementieren.
Ref: Linux-Gerätetreiber Von Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartma
Es gibt verschiedene Versionen von Spinlock:
%Vor% Im Uni-Prozessor sollte spin_lock_irqsave()
verwendet werden, wenn Daten zwischen Prozesskontext und Interruptkontext geteilt werden müssen, da in diesem Fall auch IRQ deaktiviert wird. spin_lock_irqsave()
funktionieren unter allen Umständen, aber teilweise weil sie sicher sind, sind sie auch ziemlich langsam.
Für den Fall, dass Daten über verschiedene CPUs hinweg geschützt werden müssen, ist es besser, die folgenden Versionen zu verwenden. Diese sind kostengünstiger, da IRQs in diesem Fall nicht deaktiviert werden:
In Einzelprozessorsystemen hat das Aufrufen von spin_lock_irqsave(&xxx_lock, flags);
den gleichen Effekt wie das Deaktivieren von Interrupts, die den erforderlichen Interrupt-Parallelschutz ohne unnötigen SMP-Schutz bereitstellen. In Multiprozessorsystemen deckt dies jedoch sowohl Interrupt- als auch SMP-Parallelitätsprobleme ab.
Suchen Sie die folgenden zwei Abschnitte in Betriebssystem Drei einfache Teile , die hilfreich sein könnten:
Bei Spin-Locks können im Einzel-CPU-Fall Performance-Overheads auftreten ziemlich schmerzhaft; Stellen Sie sich den Fall vor, in dem der Faden, der das Schloss hält, ist in einem kritischen Abschnitt vorweggenommen. Der Scheduler könnte dann ausgeführt werden jeden anderen Thread (stell dir vor, es gibt N - 1 andere), von denen jeder versucht das Schloss zu besetzen. In diesem Fall wird jeder dieser Threads für die Dauer einer Zeitscheibe drehen, bevor die CPU aufgegeben wird, a Verschwendung von CPU-Zyklen.
Auf mehreren CPUs funktionieren Spinlocks jedoch einigermaßen gut (wenn die Anzahl der Threads ungefähr gleich der Anzahl von Threads ist) CPUs). Das Denken ist wie folgt: Stellen Sie sich Thread A auf CPU 1 und Fädle B auf CPU 2, beide kämpfen um eine Sperre. Wenn Thread A (CPU 1) nimmt das Schloss, und dann versucht Thread B, B dreht sich (auf CPU 2). Vermutlich ist der kritische Abschnitt jedoch kurz, und somit bald auch der Sperre wird verfügbar und wird von Thread B übernommen warten Sie auf eine Sperre, die auf einem anderen Prozessor gehalten wird, vergeudet nicht viele Zyklen Dieser Fall und damit kann effektiv sein
Tags und Links linux-kernel spinlock