David Rodríguez - dribeas schrieb in einem Kommentar zu StackOverflow, dass "nicht alle Sammlungen ohne Sperren implementiert werden können". Ich bin mir nicht sicher, ob dies wahr ist, und ich kann so oder so keinen Beweis finden.
Diese Aussage ist nicht sehr präzise, aber lassen Sie mich versuchen, sie etwas formeller umzuformulieren: Für jeden Sammlungstyp gibt es einen sperrenfreien Sammlungstyp LF , der die gleichen Operationen bietet, und für jede Operation in LF hat die gleiche Big-O-Komplexität wie die entsprechende Operation an .C
C
C
C
Ich erwarte übrigens keine Transformation.
LOCK
Anweisung der CPU, sondern den Thread-Scheduler über Mutexe / Semaphoren / etc.Antworten:
Da ich selbst etwas verwirrt war, beginne ich mit der Klärung einiger Konzepte in der Frage.
Sammlung . Ich sehe keinen Grund, Zeit damit zu verbringen, genau zu definieren, was "Sammlung" bedeutet, wenn wir einfach fragen können, was für Datenstrukturen im Allgemeinen passiert. Eine Datenstruktur belegt einen Speicherplatz und verfügt über einige Operationen , die auf diesen Speicher zugreifen und von Benutzern aufgerufen werden können . Diese Benutzer können unterschiedliche Prozessoren oder nur unterschiedliche Threads sein, es geht uns nichts an. Alles was zählt ist, dass sie Operationen parallel ausführen können.
Schlossfrei . Herlihy und Boss sagen, dass eine Datenstruktur sperrfrei ist, wenn ein abstürzender Benutzer die weitere Verwendung der Datenstruktur nicht verhindert. Stellen Sie sich zum Beispiel vor, man gießt Wasser auf einen Prozessor, der gerade einen Knoten in einen sortierten Satz einfügt. Wenn andere Prozessoren später versuchen, in diese sortierte Gruppe einzufügen, sollten sie erfolgreich sein. ( Edit: Nach dieser Definition ist es der Fall , dass , wenn eine Datenstruktur , Einsatzschlösser dann ist es nicht sperren frei, aber es ist nicht der Fall , dass , wenn eine Datenstruktur Sperren nicht verwenden , dann ist es Lock-frei.)
Mit dieser Definition sagen Herlihy und Boss im Grunde, dass die Antwort darin besteht, kritische Regionen in Transaktionen umzuwandeln.
Aber, fragen Sie sich vielleicht, hat dies die gleiche Komplexität? Ich bin mir nicht sicher, ob die Frage Sinn macht. Überlegen Sie
push(x) { lock(); stack[size++] = x; unlock(); }
. Ist das eine konstante Zeitoperation? Wenn Sie den Sperrvorgang und damit andere Benutzer ignorieren, können Sie mit JA antworten. Wenn Sie andere Benutzer nicht ignorieren möchten, können Sie nicht sagen, ob der Push in konstanter Zeit ausgeführt wird. Wenn Sie eine Ebene höher gehen und sehen, wie der Stapel von einem bestimmten Algorithmus verwendet wird, können Sie möglicherweise sagen, dass der Push immer eine konstante Zeit in Anspruch nimmt (gemessen jetzt an der Eingabe Ihres parallelen Algorithmus). Aber das ist wirklich eine Eigenschaft Ihres Algorithmus, daher ist es nicht sinnvoll zu sagen, dass Push eine konstante Zeitoperation ist .Wenn Sie ignorieren, wie lange ein Benutzer, der eine Operation ausführt, auf andere Benutzer wartet, beantwortet die Verwendung von Transaktionen anstelle kritischer Bereiche Ihre Frage positiv. Wenn Sie die Wartezeit nicht ignorieren, müssen Sie sich ansehen, wie die Datenstruktur verwendet wird.
quelle
push
oben angegebene Operation keine Operation mit konstanter Zeit ist. Für eine feste Anzahl von Prozessoren, und eine gemeinsame Implementierunglock
davon garantiert keinen Hunger, nimmt die obige Operation (im schlimmsten Fall für einen gegebenen Prozessor N_proc * O (1), was naiv als O (1) angenommen werden kann ( Anzahl der Prozessoren, die in die verborgene KonstanteIch denke, dass "COLLECTIONS" für "Warteschlangen, Stapel, verknüpfte Listen, Bäume, ..." steht.
Von http://www.cl.cam.ac.uk/research/srg/netos/lock-free/
Durch sorgfältiges Design und Implementierung können Datenstrukturen erstellt werden, die für die gleichzeitige Verwendung sicher sind, ohne dass Sperren verwaltet oder Threads blockiert werden müssen. Diese nicht blockierenden Datenstrukturen können die Leistung steigern, indem sie zusätzliche Parallelität ermöglichen, und die Robustheit verbessern, indem einige der Probleme vermieden werden, die durch Prioritätsumkehr in lokalen Einstellungen oder Maschinen- und Verbindungsfehler in verteilten Systemen verursacht werden.
Die beste allgemeine Einführung in unsere nicht blockierenden Algorithmen ist das derzeit eingereichte Papier Concurrent Programming without Locks, das unsere Entwürfe für das Vergleichen und Austauschen von mehreren Wörtern, den wortbasierten Software-Transaktionsspeicher und den objektbasierten Software-Transaktionsspeicher abdeckt.
Wenn "sperrenfrei" bedeutet "Semaphores, Mutex, Monitore usw. des Betriebssystems nicht verwenden ...", dann denke ich (aber ich bin kein Experte), dass jede Sammlung mit atomarem Lese- / Schreibzugriff sperrenfrei gemacht werden kann. Ändern Sie Grundelemente, die von der Hardware unterstützt werden müssen.
Eine ausführliche Dokumentation zu diesem Thema finden Sie online:
http://www.google.it/search?q=lock+free+algorithm+filetype%3Apdf
(... und weitere Verweise am Ende jedes Dokuments)
quelle