2013-04-30 10 views
31

Der Hauptgrund für die Verwendung von Atomics über Mutexe ist, dass Mutexe teuer sind, aber das Standardspeichermodell für atomicsmemory_order_seq_cst ist, ist das nicht genauso teuer?Ist die Synchronisation mit `std :: mutex` langsamer als mit` std :: atomic (memory_order_seq_cst) `?

Frage: Kann gleichzeitig ein Programm, das Sperren verwendet, so schnell sein wie das gleichzeitige sperrfreie Programm?

Wenn ja, ist es möglicherweise nicht die Mühe wert, es sei denn, ich möchte memory_order_acq_rel für Atomics verwenden.


Edit: ich etwas fehlt möglicherweise aber Lock-Basis kann nicht schneller sein als Lock-frei, weil jede Sperre wird auch eine vollständige Speicherbarriere sein. Aber mit Lock-Free ist es möglich, Techniken zu verwenden, die weniger restriktiv sind als Speicherbarrieren.

Also zurück zu meiner Frage, ist Lock-Free schneller als Sperre basiert in neuen C++ 11 Standard mit Standard memory_model?

Ist "lock-free> = lock-based wenn gemessen in Leistung" wahr? Nehmen wir 2 Hardware-Threads an.


Edit 2: Meine Frage ist nicht über den Fortschritt garantiert, und vielleicht aus dem Zusammenhang gerissen "lock-free" Ich verwende.

Grundsätzlich, wenn Sie 2 Threads mit gemeinsamem Speicher haben, und die einzige Garantie, die Sie benötigen, ist, wenn ein Thread schreibt, dann kann der andere Thread nicht lesen oder schreiben, meine Annahme ist, dass eine einfache atomare compare_and_swap Operation wäre viel schneller als das Sperren eines Mutex.

Weil, wenn ein Thread niemals den Shared Memory berührt, wirst du endlos gesperrt und entsperrt ohne Grund, aber mit atomaren Operationen benutzt du nur 1 CPU Zyklus jedes Mal.

In Bezug auf die Kommentare ist eine Spin-Lock vs Mutex-Sperre sehr unterschiedlich, wenn es sehr wenig Konkurrenz gibt.

+0

Nun, es gibt verschiedene Fortschrittsgarantien zwischen Locks, Lock-Free und Wait-Free-Code. –

+8

[Pflichtlektüre] (http://www.1024cores.net/home/lock-free-algorithms). –

+1

Uhr: https://www.youtube.com/watch?v=DCdGlxBbKU4 – NoSenseEtAl

Antwort

53

Lockfree Programmierung ist über Fortschritt garantiert: Von stärksten zur schwächsten, das ist Wartefrei, schleusenfreien, hindernisfreie und Blockierung.

Eine Garantie ist teuer und hat einen Preis. Je mehr Garantien Sie wünschen, desto mehr zahlen Sie. Im Allgemeinen hat ein Blockierungsalgorithmus oder eine Datenstruktur (z. B. mit einem Mutex) die größten Freiheiten und ist daher möglicherweise der schnellste. Ein wartefreier Algorithmus für das andere Extrem muss bei jedem Schritt atomare Operationen verwenden, die viel langsamer sein können.

Das Erhalten einer Sperre ist eigentlich ziemlich billig, also sollten Sie sich nie darum kümmern, ohne ein tiefes Verständnis des Themas zu haben. Darüber hinaus sind Blocking-Algorithmen mit Mutexe viel einfacher zu lesen, zu schreiben und zu begründen. Im Gegensatz dazu sind selbst die einfachsten blockierungsfreien Datenstrukturen das Ergebnis langer, fokussierter Forschung, die jeweils einen oder mehrere Doktortitel wert sind.

Auf den Punkt gebracht, handeln Lock- oder Wait-Free-Algorithmen mit der schlechtesten Latenz für mittlere Latenz und Durchsatz. Alles ist langsamer, aber nichts ist jemals sehr langsam.Dies ist ein ganz besonderes Merkmal, das nur in ganz bestimmten Situationen (wie Echtzeitsystemen) nützlich ist.

+0

ok - aber 2 Threads mit gemeinsamen Daten .. nicht zustimmen, dass ein Spin-Lock ist schneller als ein Blockierschloss? – jaybny

+0

zum Beispiel eine Trading-Anwendung, die Ticks von 2 Börsen auf 2 Threads hört. wäre ein Spin-Lock nicht viel schneller als Mutex? – jaybny

+4

@jaybny: Nein, warum. Und ein Spinlock ist auch ein Schloss. Es ändert nichts an den grundlegenden Garantien. Und bitte sehen Sie sich die Implementierung des Pthread Mutex für eine angenehme Überraschung an. –

2

Eine Sperre erfordert mehr Operationen als eine einfache atomare Operation. Im einfachsten Fall ist memory_order_seq_cst etwa doppelt so schnell wie das Sperren, da das Sperren in der Regel mindestens zwei atomare Operationen erfordert (eines zum Sperren, eines zum Entsperren). In vielen Fällen braucht es sogar mehr. Sobald Sie jedoch beginnen, die Speicheraufträge zu nutzen, kann es viel schneller sein, weil Sie bereit sind, weniger Synchronisation zu akzeptieren.

Auch werden Sie oft sehen, "Sperralgorithmen sind immer so schnell wie Lock-free-Algorithmen." Das ist etwas wahr. Die Grundidee ist, dass, wenn der schnellste Algorithmus frei von Sperren ist, der schnellste Algorithmus ohne Lock-Free-Garantie ALSO der gleiche Algorithmus ist! Wenn jedoch das schnellste Algortihm Sperren erfordert, müssen diejenigen, die lockfreie Garantien verlangen, einen langsameren Algorithmus finden.

Im Allgemeinen werden Sie lockfree Algorithmen in einigen wenigen Low-Level-Algorithmen sehen, wo die Leistung der Verwendung von spezialisierten Opcodes hilft. In fast allen anderen Codes ist das Sperren mehr als zufriedenstellend und viel einfacher zu lesen.

+0

"Locking-Algorithmen sind immer so schnell wie Lock-Free-Algorithmen." - Ich verstehe das nicht. Eine thread-safe-Schleife mit gemeinsam genutztem Speicher wird viel schneller sein und eine einfache compare_exchange- und dann eine lock (mutex) -entsperrung (mutex) durchführen. vor allem wenn es nie einen Streit von einem anderen Thread gibt. – jaybny

Verwandte Themen