Frage

Wie oft findet man sich tatsächlich spinlocks in Ihrem Code verwenden? Wie häufig ist es auf eine Situation zu kommen, wo mit einem arbeitsreiches Schleife trifft tatsächlich die Verwendung von Sperren?
Persönlich, wenn ich irgendeine Art von Code schreiben, die Thread-Sicherheit erfordert, neige ich dazu, es mit unterschiedlichen Synchronisations Primitiven zum Benchmark, und soweit es geht, scheint es, wie Vorhängeschlösser bessere Leistung gibt als spinlocks verwenden. Egal, für wie wenig Zeit ich die Sperre tatsächlich halten, ist die Menge des Anstoßes I erhalten, wenn spinlocks verwendet, ist weit größer als die Menge, die ich verwenden, Schlösser bekommen (natürlich, ich meine Tests auf einem Multi-Prozessor-Maschine ausgeführt wird).

Ich weiß, dass es wahrscheinlicher ist, über eine spinlock in „low-level“ Code zu kommen, aber ich bin daran interessiert zu wissen, ob Sie es nützlich, auch eine High-Level Art der Programmierung finden?

War es hilfreich?

Lösung

Es hängt davon ab, was Sie tun. Im allgemeinen Anwendungscode, möchten Sie spinlocks vermeiden.

In Low-Level-Zeug wo es nur die Sperre für ein paar Anweisungen halten, und die Latenzzeit ist wichtig, eine spinlock Matte eine bessere Lösung als ein Schloss sein. Aber diese Fälle sind selten, vor allem in der Art der Anwendungen, bei denen C # wird normalerweise verwendet.

Andere Tipps

In C #, „Spin Schlösser“ gewesen, in meiner Erfahrung fast immer schlechter als eine Sperre nehmen -. Es ist ein seltenes Ereignis, wo Spin-Locks eine Sperre übertreffen

Allerdings, das ist nicht immer der Fall. .NET 4 ist das Hinzufügen einer System.Threading .SpinLock Struktur. Dies bietet Vorteile in Situationen, in denen eine Sperre für eine sehr kurze Zeit gehalten wird, und immer wieder ergriffen werden. Aus der MSDN-Dokumentation auf Datenstrukturen für die parallele Programmierung :

  

In Szenarien, in denen die Wartezeit für die Sperre wird voraussichtlich kurz, SpinLock bietet eine bessere Leistung als andere Formen der Verriegelung.

Spin Sperren können übertreffen andere Mechanismen in Fällen Sperren, wo man so etwas wie Verriegelung durch einen Baum tun - wenn Sie nur Sperren auf jedem Knoten für eine sehr, sehr kurze Zeit haben, können sie durchführen, um ein traditionelle sperren. Ich lief in diesen in einer Rendering-Engine mit einer Multi-Thread-Szene zu aktualisieren, an einer Punkt -. Spinlocks mit Monitor.Enter zu entwickeln Profil aus Sperren

Für meine Arbeit in Echtzeit, insbesondere mit Gerätetreibern, habe ich sie ein gutes Stück verwendet. Es stellt sich heraus, dass (wenn ich endlich diese zeitlich begrenzten) wie ein Semaphor für ein Sync-Objekt wartet auf eine Hardware gebunden kaut mindestens 20 Mikrosekunden unterbrechen, egal wie lange es dauert tatsächlich für die Unterbrechung auftritt. Eine einzige Prüfung eines Memory-Mapped-Hardware-Register, um einen Scheck zu RDTSC gefolgt (für eine Auszeit zu ermöglichen, so dass Sie die Maschine nicht einsperren) im Hoch nannosecond Bereich (basicly unten im Rauschen). Für Hardware-Ebene Handshaking, die nicht viel Zeit überhaupt nehmen sollte, ist es wirklich schwierig, eine spinlock zu schlagen.

Meine 2c: Wenn die Updates einige Zugangskriterien erfüllen, dann sind sie gut spinlock Kandidaten:

  • schnell , dh Sie Zeit haben die spinlock, führen Sie die Updates und lassen Sie die spinlock in einem einzigen Thread Quanten zu erwerben, so dass Sie nicht vorweggenommen tun bekommen, während die spinlock halten
  • lokalisierte alle Daten, die Sie Update in vorzugsweise einer einzigen Seite werden die bereits geladen ist, Sie wollen keinen TLB, während Sie die spinlock halten, und Sie auf jeden Fall keine Seitenfehler tauschen wollen lesen!
  • Atom Sie keine andere Sperre müssen die Operation auszuführen, dh. warten nie unter spinlock für Schlösser.

Für alles, was jedes Potenzial hat, zu erhalten, sollten Sie eine benannte Verriegelungsstruktur (Veranstaltungen, Mutex, Semaphore usw.) verwendet werden.

Ein Anwendungsfall für Spin-Locks ist, wenn man sehr niedrige Konkurrenz erwarten würde, aber werden eine Menge von ihnen haben. Wenn Sie für rekursive Verriegelung keine Unterstützung benötigen, ein Spinlock kann in einem einzigen Byte implementiert werden, und wenn Conten sehr niedrig ist dann der CPU-Zyklus Abfall vernachlässigbar ist.

Für einen praktischen Anwendungsfall, ich habe oft Anordnungen von tausenden von Elementen, in denen Updates auf verschiedene Elemente des Arrays sicher parallel passieren kann. Die Chancen von zwei Threads versuchen, das gleiche Element zur gleichen Zeit zu aktualisieren sind sehr klein (niedrige Konkurrenz), aber ich brauche eine Sperre für jedes Element (Ich werde eine Menge von ihnen haben). In diesen Fällen zuteilen ich in der Regel eine Reihe von ubytes der gleichen Größe wie die Anordnung parallel ich die Aktualisierung und Umsetzung spinlocks inline als (in der Programmiersprache D):

while(!atomicCasUbyte(spinLocks[i], 0, 1)) {}
    myArray[i] = newVal;
atomicSetUbyte(spinLocks[i], 0);

Auf der anderen Seite, wenn ich regelmäßig Schlösser verwenden hätte, würde ich habe ein Array von Zeigern auf Objekte zuweisen, und dann für jedes Element dieses Arrays eines Mutex-Objekt zuordnen. In Szenarien, wie das oben beschrieben wird, ist dies einfach nur verschwenderisch.

Wenn Sie die Leistung kritische Codes haben und Sie haben festgestellt, dass es schneller sein muss als es derzeit ist und Sie festgestellt haben, dass der kritische Faktor ist die Verriegelungsgeschwindigkeit, dann wäre es eine gute Idee, einen Spinlock zu versuchen. In anderen Fällen, warum die Mühe? Normale Schlösser sind einfacher zu benutzen zu können.

Bitte beachten Sie folgende Punkte:

  1. Die meisten mutexe der Implementierungen für eine kleine Weile drehen, bevor der Thread eigentlich ungeplanten ist. Aus diesem Grunde ist es schwer, Thesen mutexes mit reinem spinlocks zu vergleichen.

  2. Mehrere Threads „so schnell wie möglich“ auf dem gleichen spinlock spining wird die ganze Bandbreite consome und drasticly Ihr Programm Effizienz verringern. Sie müssen durch Zugabe von noop in Ihrer spining Schleife winzige „sleeping“ Zeit hinzuzufügen.

Sie müssen so gut wie nie spinlocks im Anwendungscode verwenden, wenn alles, was Sie sollten sie vermeiden.

Das kann ich nicht, was aus irgendeinem Grund eine spinlock in c # Code zu verwenden, auf einem normalen OS ausgeführt wird. Busy Schlösser sind meist ein Abfall auf der Anwendungsebene - das Spinnen verursachen können Sie die gesamte CPU-Zeitscheibe verwenden, gegen eine Sperre wird umgehend ein Kontextwechsel verursachen, wenn nötig.

Hochleistungs Code, wo Sie nr von threads = nr Prozessoren / Kerne haben könnten in einigen Fällen profitieren, aber wenn Sie Performance-Optimierung auf dieser Ebene benötigen wahrscheinlich Next-Gen 3D-Spiel zu machen, arbeitet an einem eingebetteten Betriebssystem mit einer schlechten Synchronisation Primitiven , ein O / Treiber oder jedenfalls nicht mit c # zu schaffen.

Ich benutzte Spinlocks für die Stop-the-World-Phase des Garbage Collector in meinem HLVM Projekt, weil sie einfach und das ist ein Spielzeug VM. Allerdings Spin-Locks können in diesem Zusammenhang kontraproduktiv sein:

Einer der perf Fehler in der Glasgow Haskell Compiler der Garbage Collector ist so ärgerlich, dass es einen Namen hat, die " letzter Kern Verlangsamung “. Dies ist eine direkte Folge ihres unangemessenen Einsatzes von Spinlocks in ihrem GC und excacerbated auf Linux aufgrund seiner Scheduler aber in der Tat, kann der Effekt beobachtet werden, wenn andere Programme für die CPU-Zeit konkurrieren.

Der Effekt ist klar auf dem zweiten Diagramm hier und kann zu beeinflussen mehr gesehen als nur den letzten Kern hier , wo das Haskell-Programm Leistungsabfall über nur 5 Kern sieht.

Halten Sie diese Punkte in Ihrem Kopf, während Sie spinlocks :

  • Fast-User-Modus Ausführung.
  • Synchronisiert Threads in einem einzelnen Prozess oder mehrere Prozesse, wenn im gemeinsamen Speicher.
  • nicht zurück, bis das Objekt gehört.
  • Unterstützt keine Rekursion.
  • Verbraucht 100% der CPU, während "Warten".

Ich habe persönlich so viele Deadlocks gesehen, nur weil jemand dachte, wird es eine gute Idee sein, spinlock zu verwenden.

Seien Sie sehr vorsichtig, während spinlocks mit

(ich dies nicht genug betonen kann).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top