Read-Copy-Update

Im Computer Betriebssysteme ist "lesen Sie Kopie-Aktualisierung" (RCU) ein Synchronisationsmechanismus, der eine Art gegenseitigen Ausschluss durchführt, der manchmal als eine Alternative zu einem Schloss der Leser-Schriftstellers verwendet werden kann. Es erlaubt äußerst niedrig oben, warten Sie - frei liest. Jedoch können RCU Aktualisierungen teuer sein, weil sie die alten Versionen der Datenstruktur im Platz verlassen müssen, vorher existierende Leser unterzubringen. Diese alten Versionen werden zurückgefordert, nachdem alle vorher existierenden Leser ihre Zugänge beenden.

Übersicht

RCU zeigt las Seite kritische Abteilungen, die normalerweise durch rcu_read_lock und rcu_read_unlock abgegrenzt werden. Wie man sagt, ist jede Behauptung, die nicht innerhalb einer RCU lesen Seite kritische Abteilung ist, ein Ruhezustand, und solche Behauptungen werden nicht erlaubt, Verweisungen auf GeRCU-schützte Datenstrukturen zu halten. Jeder Zeitabschnitt, während dessen jeder Faden mindestens ein Ruhezustand wohnt, wird eine Gnadenfrist genannt. Definitionsgemäß, jede RCU lesen Sie Seite, die die kritische Abteilung in der Existenz am Anfang einer gegebenen Gnadenfrist vor dem Ende dieser Gnadenfrist vollenden muss, die die grundsätzliche durch RCU zur Verfügung gestellte Garantie einsetzt. Es stellt sich heraus, dass diese Garantie mit äußerst kleinen allgemeinen Kosten der läse Seite tatsächlich im Begrenzungsfall versorgt werden kann, der wirklich durch den Linux-Kern der Server-Klasse begriffen wird, baut, die lesen Sie Seite oben ist genau Null-.

Die grundsätzliche Garantie von RCU kann durch das Aufspalten von Aktualisierungen in die Eliminierung und Reklamationsphasen verwendet werden. Die Eliminierungsphase entfernt Verweisungen auf Datensachen innerhalb einer Datenstruktur (vielleicht durch das Ersetzen von ihnen durch Verweisungen auf neue Versionen dieser Datensachen), und kann gleichzeitig mit der RCU läsest Seite kritische Abteilungen führen. Der Grund, dass es sicher ist, die Eliminierungsphase gleichzeitig mit RCU Lesern zu führen, ist die Semantik von der modernen Zentraleinheitsgarantie, dass Leser entweder das alte oder die neue Version der Datenstruktur aber nicht einer teilweise aktualisierten Verweisung sehen werden. Sobald eine Gnadenfrist vergangen hat, kann es irgendwelche Leser nicht mehr geben, die in der alten Version Verweise anbringen, so ist es dann für die Reklamationsphase zum freien sicher (fordern) die Datensachen (zurück), die diese alte Version zusammengesetzt haben.

Das Aufspalten einer Aktualisierung in die Eliminierung und Reklamationsphasen erlaubt dem updater, die Eliminierungsphase sofort durchzuführen, und die Reklamationsphase aufzuschieben, bis alle während der Eliminierungsphase energischen Leser mit anderen Worten vollendet haben, bis eine Gnadenfrist vergangen hat.

So geht die typische RCU-Aktualisierungsfolge etwas wie der folgende:

  1. Stellen Sie sicher, dass alle Leser, die auf GeRCU-schützte Datenstrukturen zugreifen, ihre Verweisungen aus einer RCU lesen Seite kritische Abteilung ausführen.
  2. Entfernen Sie Zeigestöcke zu einer Datenstruktur, so dass nachfolgende Leser keine Verweisung darauf gewinnen können.
  3. Warten Sie seit einer Gnadenfrist, um zu vergehen, so dass alle vorherigen Leser (der noch Zeigestöcke zur im vorherigen Schritt entfernten Datenstruktur haben könnte) ihre RCU lesen Seite kritische Abteilungen vollendet haben werden.
  4. An diesem Punkt kann es keine Leser geben, die noch Verweisungen auf die Datenstruktur halten, so kann es jetzt (z.B sicher zurückgefordert, befreit werden).

Im obengenannten Verfahren führt der updater sowohl die Eliminierung als auch den Reklamationsschritt durch, aber es ist häufig für einen völlig verschiedenen Faden nützlich, die Reklamation zu tun. Das Bezugszählen kann verwendet werden, um den Leser Eliminierung so durchführen zu lassen, selbst wenn derselbe Faden beide der Aktualisierungsschritt (Schritt (2) oben) und der Reklamationsschritt durchführt (Schritt (4) oben), ist es häufig nützlich, an sie getrennt zu denken.

Gebrauch

Bezüglich Anfangs 2008 gab es fast 2,000 Gebrauch der RCU API innerhalb des Kerns von Linux, einschließlich der Netzwerkanschlussprotokoll-Stapel und des Speichermanagement-Systems.

Seit 2006 haben Forscher RCU und ähnliche Techniken zu mehreren Problemen einschließlich des Managements von in der dynamischen Analyse verwendetem metadata angewandt, die Lebenszeit von gruppierten Gegenständen führend, Gegenstand-Lebenszeit in der K42 Forschung Betriebssystem führend, und Software transactional Speicherdurchführungen optimierend. Libelle-BSD verwendet eine Technik, die RCU ähnlich ist, der am nächsten der RCU Durchführung von Linux ähnelt.

Vorteile und Nachteile

Die Fähigkeit zu warten, bis alle Leser getan werden, erlaubt RCU Lesern, viel Synchronisation in einigen Fällen des leichteren Gewichts, gar keine Synchronisation überhaupt zu verwenden. Im Gegensatz, in herkömmlicheren Schloss-basierten Schemas, müssen Leser Schwergewichtssynchronisation verwenden, um einen updater davon abzuhalten, die Datenstruktur aus unter ihnen zu löschen. Das ist, weil Schloss-basierte updaters normalerweise Datensachen im Platz aktualisieren, und deshalb Leser ausschließen müssen. Im Gegensatz nutzen RCU-basierte updaters normalerweise die Tatsache aus, die einzelnen ausgerichteten Zeigestöcken schreibt, sind auf modernen Zentraleinheiten atomar, Atomeinfügung, Eliminierung und Ersatz von Datensachen in einer verbundenen Struktur erlaubend, ohne Leser zu stören. Gleichzeitige RCU Leser können dann fortsetzen, auf die alten Versionen zuzugreifen, und können auf die Atomoperationen, die Speicherbarrieren und das geheime Lager Fräulein verzichten, die auf modernen SMP Computersystemen sogar in der Abwesenheit des Schloss-Streits so teuer sind. Die Leichtgewichtsnatur der Primitiven der läse Seite von RCU stellt zusätzliche Vorteile außer der ausgezeichneten Leistung, Skalierbarkeit und Echtzeitantwort zur Verfügung. Zum Beispiel stellen sie Immunität gegen den grössten Teil des toten Punktes und livelock Bedingungen zur Verfügung.

Natürlich hat RCU auch Nachteile. Zum Beispiel ist RCU eine Spezialtechnik, die am besten in Situationen damit arbeitet, größtenteils liest und wenige Aktualisierungen, aber ist häufig auf Aktualisierung-Only-Arbeitspensen weniger anwendbar. Für ein anderes Beispiel, obwohl die Tatsache, dass RCU Leser und updaters gleichzeitig durchführen können, ist, was die Leichtgewichtsnatur der Primitiven der läse Seite von RCU ermöglicht, können einige Algorithmen nicht verantwortlich sein, um Parallelität zu lesen zu/aktualisieren.

Trotz gut mehr als eines Jahrzehnts der Erfahrung mit RCU ist das genaue Ausmaß seiner Anwendbarkeit noch ein Forschungsthema.

Patente

Die Technik wird durch das U.S.software-Patent 5,442,758, ausgegeben am 15. August 1995 und zugeteilt Folgenden Computersystemen, sowie durch 5,608,893, 5,727,528, 6,219,690, und 6,886,162 bedeckt. Die jetzt ungültigen 4,809,168 Offenen US-Deckel eine nah zusammenhängende Technik. RCU ist auch das Thema eines Anspruchs im SCO v. Rechtssache von IBM.

RCU Beispielschnittstelle

RCU ist in mehreren Betriebssystemen verfügbar, und wurde zum Kern von Linux im Oktober 2002 hinzugefügt. Benutzerniveau-Durchführungen wie liburcu sind auch verfügbar.

Die Durchführung von RCU in der Version 2.6 des Kerns von Linux ist unter den besser bekannten RCU Durchführungen, und wird als eine Inspiration für die RCU API im Rest dieses Artikels verwendet. Die Kern-API (Anwendung, Schnittstelle Programmierend), ist ziemlich klein:

  • rcu_read_lock : Kennzeichnet eine GeRCU-schützte Datenstruktur, so dass sie für die volle Dauer dieser kritischen Abteilung nicht zurückgefordert wird.
  • rcu_read_unlock : Verwendet von einem Leser, um den Wiederkläger zu informieren, dass der Leser über eine RCU lesen Seite kritische Abteilung herrscht. Bemerken Sie, dass RCU lesen Seite kritische Abteilungen verschachtelt werden kann und/oder Überschneidung.
  • synchronize_rcu : Es blockiert bis zum ganzen Vorherexistieren RCU lesen Seite haben kritische Abteilungen auf allen Zentraleinheiten vollendet. Bemerken Sie, dass das für keine nachfolgende RCU lesen Seite auf kritische Abteilungen notwendigerweise warten wird, um zu vollenden. Denken Sie zum Beispiel die folgende Folge von Ereignissen:

ZENTRALEINHEIT 0 ZENTRALEINHEIT 1 ZENTRALEINHEIT 2

---------------------------------------------------------

1. rcu_read_lock

2. geht in synchronize_rcu ein

3. rcu_read_lock

4. rcu_read_unlock

5. Ausgänge synchronize_rcu

6. rcu_read_unlock

</pre>

:Since ist die API, die sich belaufen muss, wenn Leser getan werden, ist seine Durchführung Schlüssel zu RCU. Für RCU, um in allen außer dem am meisten gelesenen - intensive Situationen nützlich zu sein, 's oben auch ziemlich klein sein muss.

:Alternatively, statt des Blockierens, synchronize_rcu kann eine Rückrufaktion einschreiben, die nach der ganzen andauernden RCU läsest Seite anzurufen ist, die kritische Abteilungen vollendet haben. Diese Rückrufaktionsvariante wird der Kern von Linux herbeigerufen.

  • rcu_assign_pointer : Der updater verwendet diese Funktion, einen neuen Wert einem GeRCU-schützten Zeigestock zuzuteilen, um die Wertänderung vom updater bis den Leser sicher mitzuteilen. Diese Funktion gibt den neuen Wert zurück, und führt auch irgendwelche für eine gegebene Zentraleinheitsarchitektur erforderlichen Speicherbarriere-Instruktionen durch. Vielleicht wichtiger dient es dem Dokument, welche Zeigestöcke durch RCU geschützt werden.
  • rcu_dereference_pointer : Der Leser-Gebrauch, um einen GeRCU-schützten Zeigestock herbeizuholen, der einen Wert zurückgibt, der dann sicher dereferenced sein kann. Es führt auch irgendwelche erforderlichen Speicherbarriere-Instruktionen für eine gegebene Zentraleinheitsarchitektur durch. Der Wert, der dadurch zurückgegeben ist, ist nur innerhalb des Umgebens RCU lesen Seite kritische Abteilung gültig. Als mit ist eine wichtige Funktion dessen zum Dokument, welche Zeigestöcke durch RCU geschützt werden.

Das folgende Diagramm zeigt, wie jede API unter dem Leser, updater, und Wiederkläger kommuniziert.

Die RCU Infrastruktur beobachtet die Zeitfolge, und Beschwörungen, um zu bestimmen, wenn (1) Beschwörungen zu ihren Anrufern und (2) zurückkehren können, Rückrufaktionen können angerufen werden. Effiziente Durchführungen der RCU Infrastruktur machen schweren Gebrauch von batching, um ihr oberirdisches über vielen Gebrauch des entsprechenden APIs zu amortisieren.

Was ist eine einfache Durchführung von RCU?

RCU hat äußerst einfache "Spielzeug"-Durchführungen, die dem Verstehen von RCU helfen können. Diese Abteilung präsentiert eine solche "Spielzeug"-Durchführung, die in einer Nichtvorkaufsumgebung arbeitet.

Leere rcu_read_lock (Leere) {}\

Leere rcu_read_unlock (Leere) {}\

Leere call_rcu (Leere (*callback) (Leere *), Leere *arg)

{\

//fügen Sie callback/arg Paar zu einer Liste hinzu

}\

Leere synchronize_rcu (Leere)

{\

int ZE, ncpus = 0;

for_each_cpu (ZE)

schedule_current_task_to (ZE);

weil jeder Zugang im call_rcu verzeichnet

Zugang-> Rückrufaktion (Zugang-> arg);

}\</pre>

Sie können ignorieren und ohne viel zu fehlen. Aber hier sind sie irgendwie.

#define rcu_assign_pointer (p, v) ({\

smp_wmb ; \

(p) = (v); \

})

#define rcu_dereference_pointer (p) ({\

typeof (p) _value = (p); \

smp_rmb ;/*, der nicht auf allen Architekturen */\erforderlich

ist

(_value); \

})

</pre>

Bemerken Sie, dass und absolut nichts tun. Das ist die große Kraft von klassischem RCU in einem Nichtvorkaufskern: Lesen Seite oben ist genau Null, weil die Speicherbarriere wirklich nur auf Alpha-Zentraleinheiten im DEZ erforderlich ist. Und es gibt gar keinen Weg, der an einem Zyklus des toten Punktes teilnehmen, einen Echtzeitprozess veranlassen kann, seinen Terminplanungstermin, jäh hinabstürzende Vorzugsinversion zu verpassen, oder auf hohen Schloss-Streit hinauszulaufen.

Die Durchführung von Bewegungen der Anrufer von synchronize_cpu zu jeder Zentraleinheit, so bis zu allen Zentraleinheiten blockierend, ist im Stande gewesen, den Zusammenhang-Schalter durchzuführen. Da es keine Vorkaufsrecht-Punkte innerhalb einer RCU lesen Seite kritische Abteilung geben kann, wenn eine gegebene Zentraleinheit einen Zusammenhang-Schalter durchführt (um einen anderen Prozess zu planen), wissen wir, dass es das ganze Vorangehen RCU lesen Seite kritische Abteilungen vollendet haben muss. Sobald alle Zentraleinheiten einen Zusammenhang-Schalter, dann das ganze Vorangehen RCU lesen Seite durchgeführt haben, die kritische Abteilungen vollendet haben werden.

Analogie mit dem Leser-Schriftsteller, der sich schließen lässt

Obwohl RCU auf viele verschiedene Weisen verwendet werden kann, ist eine sehr übliche Anwendung von RCU dem Leser-Schriftsteller analog, der sich schließen lässt. Die folgenden codieren nebeneinander Anzeigeshows, wie nah verwandter Leser-Schriftsteller, der sich (links) schließen lässt, und RCU (rechts) sein können.

1 struct el {1 struct el {\

2 struct list_head LP; 2 struct list_head LP;

3 langer Schlüssel; 3 langer Schlüssel;

4 spinlock_t mutex; 4 spinlock_t mutex;

5 int Daten; 5 int Daten;

6/* Andere Datenfelder */6/* Andere Datenfelder * /

7\; 7\;

8 DEFINE_RWLOCK (listmutex); 8 DEFINE_SPINLOCK (listmutex);

9 LIST_HEAD (Kopf); 9 LIST_HEAD (Kopf);

1 int Suche (langer Schlüssel, interne Nummer *result) 1 int Suche (langer Schlüssel, interne Nummer *result)

2 {2 {\

3 struct el *p; 3 struct el *p;

4 4

5 read_lock (&listmutex); 5 rcu_read_lock ;

6 list_for_each_entry (p, &head, LP) {6 list_for_each_entry_rcu (p, &head, LP) {\

7 wenn (p-> Schlüssel == Schlüssel) {7 wenn (p-> Schlüssel == Schlüssel) {\

8 *result = p-> Daten; 8 *result = p-> Daten;

9 read_unlock (&listmutex); 9 rcu_read_unlock ;

10 Rückkehr 1; 10 Rückkehr 1;

11} 11 }\

12} 12 }\

13 read_unlock (&listmutex); 13 rcu_read_unlock ;

14 Rückkehr 0; 14 Rückkehr 0;

15} 15 }\

1 interne Nummer löscht (langer Schlüssel) 1 interne Nummer löscht (langer Schlüssel)

2 {2 {\ 3 struct el *p; 3 struct el *p; 4 4

5 write_lock (&listmutex); 5 spin_lock (&listmutex);

6 list_for_each_entry (p, &head, LP) {6 list_for_each_entry (p, &head, LP) {\

7 wenn (p-> Schlüssel == Schlüssel) {7 wenn (p-> Schlüssel == Schlüssel) {\

8 list_del (&p->lp); 8 list_del_rcu (&p->lp);

9 write_unlock (&listmutex); 9 spin_unlock (&listmutex);

10 synchronize_rcu ;

10 kfree (p); 11 kfree (p);

11 Rückkehr 1; 12 Rückkehr 1;

12} 13 }\

13} 14 }\

14 write_unlock (&listmutex); 15 spin_unlock (&listmutex);

15 Rückkehr 0; 16 Rückkehr 0;

16} 17 }\

</pre>

Die Unterschiede zwischen den zwei Annäherungen sind ziemlich klein. Lesen Seite, die Bewegungen zu und, Aktualisierungsseite schließt, die Bewegungen von einem Leser-Schriftsteller schließt, lässt sich zu einem einfachen spinlock und einem Vorangehen schließen.

Jedoch gibt es einen potenziellen Fang: Die lesen Sie Seite und Aktualisierungsseite kritische Abteilungen können jetzt gleichzeitig laufen. In vielen Fällen wird das kein Problem sein, aber es ist notwendig, sorgfältig trotzdem zu überprüfen. Zum Beispiel, wenn vielfache unabhängige Listenaktualisierungen als eine einzelne Atomaktualisierung gesehen werden müssen, wird das Umwandeln zu RCU spezielle Sorge verlangen.

Außerdem die Anwesenheit der Mittel, die die RCU Version dessen jetzt blockieren kann. Wenn das ein Problem ist, konnte wie im Platz dessen verwendet werden. Das ist in der Kombination mit dem Bezugszählen besonders nützlich.

Erklärung des Namens

Der Name kommt aus der Weise, wie RCU verwendet wird, um eine verbundene Struktur im Platz zu aktualisieren.

Ein Faden, der möchte tun, verwendet das die folgenden Schritte:

  • schaffen Sie eine neue Struktur,
  • kopieren Sie die Daten von der alten Struktur in die neue, und sparen Sie einen Zeigestock zur alten Struktur,
  • modifizieren Sie das neue, kopierte, Struktur
  • aktualisieren Sie den globalen Zeigestock, um sich auf die neue Struktur, und dann zu beziehen
  • der Schlaf bis zum Betriebssystemkern beschließt, dass es das verlassenes Verwenden keiner Leser der alten Struktur, zum Beispiel, im Kern von Linux, durch das Verwenden synchronize_rcu gibt.

Wenn der Faden, der die Kopie gemacht hat, durch den Kern erweckt wird, kann es sicher deallocate die alte Struktur.

So wird die Struktur gleichzeitig mit einem Faden-Kopieren gelesen, um eine Aktualisierung, folglich der Name "Aktualisierung der läse Kopie" zu tun. Die Abkürzung "RCU" war einer von vielen Beiträgen durch die Gemeinschaft von Linux. Andere Namen für ähnliche Techniken schließen passive Anordnung ein, und Abgeordneter fügen sich durch VM/XA Programmierer und Generationen durch K42- und Tornado-Programmierer.

Geschichte

Techniken und Mechanismen, die RCU ähneln, sind mehrmals unabhängig erfunden worden:

  1. H. T. Kung und Q. Lehman haben Gebrauch von Müllmännern beschrieben, um RCU ähnlichen Zugang zu einem binären Suchbaum durchzuführen.
  2. Udi Manber und Richard Ladner haben die Arbeit von Kung und Lehmans zu nicht erweitert Müll hat Umgebungen durch das Aufschieben der Reklamation gesammelt, bis alle Fäden, die in der Eliminierungszeit laufen, geendet haben, der in Umgebungen arbeitet, die langlebige Fäden nicht haben.
  3. Richard Rashid u. a. beschrieben hat eine faule Durchführung der Übersetzung lookaside Puffers (TLB), die das Zurückfordern des virtuellen Adressraums bis zu allen Zentraleinheiten aufgeschoben hat, ihren TLB gespült, der im Geist einigen RCU Durchführungen ähnlich ist.
  4. J. Hennessy, D. Osisek und J. Seigh wurden amerikanische Offene 4,809,168 1989 (da abtrünnig) gewährt. Dieses Patent beschreibt einen RCU ähnlichen Mechanismus, der anscheinend in VM/XA auf IBM Mainframes verwendet wurde.
  5. William Pugh hat einen RCU ähnlichen Mechanismus beschrieben, der sich auf das ausführliche Fahne-Setzen durch Leser verlassen hat.
  6. Aju John hat eine RCU ähnliche Durchführung vorgeschlagen, wo updaters einfach seit einer festen Zeitspanne unter der Annahme warten, dass Leser alle innerhalb dieser festen Zeit vollenden würden, wie in einem harten Echtzeitsystem passend sein könnte. Van Jacobson hat ein ähnliches Schema 1993 (wörtliche Kommunikation) vorgeschlagen.
  7. J. Slingwine und P. E. McKenney haben amerikanische Offene 5,442,758 im August 1995 erhalten, der RCU, wie durchgeführt, in DYNIX/ptx und später im Kern von Linux beschreibt.
  8. B. Gamsa, O. Krieger, J. Appavoo und M. Stumm haben einen RCU ähnlichen Mechanismus beschrieben, der in der Universität der Toronto Tornado-Forschung Betriebssystem und die nah zusammenhängende Forschung von IBM Research K42 Betriebssysteme verwendet ist.
  9. Rostiger Russell und Phil Rumpf haben RCU ähnliche Techniken beschrieben, um Entleerung von Kernmodulen von Linux zu behandeln.
  10. D. Sarma hat RCU zur Version 2.5.43 des Kerns von Linux im Oktober 2002 hinzugefügt.
  11. Robert Colvin. hat formell einen faulen gleichzeitigen listenbasierten Satz-Algorithmus nachgeprüft, der RCU ähnelt.

Siehe auch

Referenzen

Links

  • (1995) "Apparat und Methode, um zu erreichen, haben gegenseitigen Oberausschluss reduziert und Kohärenz in einem Mehrverarbeiter-System aufrechtzuerhalten, das Ausführungsgeschichte und Faden verwertet, der" kontrolliert
  • Paul McKenney: Sleepable RCU. Linux wöchentliche Nachrichten.

Der Grundsatz von Babinet / Tim Lander
Impressum & Datenschutz