Frage

Ich habe einige unveränderliche Datenstrukturen, die ich möchte mit Verweis zählt verwalten, so dass sie über Threads auf einem SMP-System teilen.

Hier ist, was die Freigabe-Code sieht aus wie:

void avocado_release(struct avocado *p)
{
    if (atomic_dec(p->refcount) == 0) {
        free(p->pit);
        free(p->juicy_innards);
        free(p);
    }
}

Does atomic_dec benötigen eine Speicherbarriere darin? Wenn ja, welche Art von Speicherbarriere?

Zusätzliche Hinweise: Der Antrag muss auf PowerPC laufen und x86, so dass jeder prozessorspezifische Informationen begrüßt. Ich weiß schon, über den GCC-Atom builtins. Wie für Unveränderlichkeit ist die refcount der nur Feld, dass Änderungen über die Dauer des Objekts.

War es hilfreich?

Lösung

Auf x86, wird es in ein Schloss drehen Vorangestellte Montageanleitung, wie LOCK XADD.
eine einzige Anweisung zu sein, ist es nicht unterbrechbare. Als zusätzlichen „feauture“, der Sperr Präfix führt zu einer vollständigen Speichergrenze:

  

„... gesperrt Operationen serialisiert werden alle ausstehenden Lade- und Speicheroperationen (das heißt, warten, bis sie vollständig).“ ... "Locked-Operationen sind Atom in Bezug auf alle anderen Speicheroperationen und alle äußerlich sichtbaren Ereignisse. Nur Befehlsabruf und Seitentabellenzugriffe gesperrt Anweisungen passieren kann. Locked Anweisungen zum Synchronisieren von Daten verwendet werden kann durch einen Prozessor geschrieben und durch einen anderen Prozessor gelesen .“ - Intel® 64 und IA-32 Architektur Software Developer Handbuch Kapitel 8.1.2.

Eine Speicherbarriere Tatsache wird in als Dummy LOCK OR LOCK AND oder in beiden implementiert .NET und der JAVA JIT auf x86 / x64.
So haben Sie einen vollständigen Zaun auf x86 als zusätzliche Bonus haben, ob Sie sie mögen oder nicht. :)

Auf PPC, ist es anders. Eine LL / SC Paar - lwarx & stwcx - mit einer im Inneren Subtraktion kann verwendet werden, die Speicheroperanden in ein Register zu laden, eine subtrahierte, dann ist es entweder zurück zu schreiben, wenn es keine andere Speicher an den Zielort war, oder die gesamte Schleife wiederholt, wenn es gab. Ein LL / SC kann unterbrochen werden.
Es ist auch nicht einen automatischen Voll Zaun bedeuten.
Dies gilt jedoch nicht gefährden die Unteilbarkeit des Zählers in keiner Weise.
Es bedeutet nur, dass in dem x86-Fall, Sie passieren auch einen Zaun zu bekommen, „kostenlos“.
auf PPC, kann man einen vollständigen Zaun einfügen, indem Sie ein (lw)sync Anweisung .

Alles in allem sind explizite Gedächtnis Barrieren nicht notwendig für die Atom Zähler richtig funktioniert.

Andere Tipps

Es ist wichtig, zwischen Atom-Zugriffen (die Garantie, dass das Lese- / modify / Schreiben des Wert ausführt, als eine Atomeinheit) und einen Speicher Umordnung zu unterscheiden.

Speicherbarrieren verhindern Neuordnungs liest und schreibt und Nachbestellung ist vollständig orthogonal zu Unteilbarkeit. Zum Beispiel auf PowerPC, wenn Sie den effizienteste Atomschritt implementieren möglich, dann wird es nicht verhindern Nachbestellung. Wenn Sie Neuordnungs verhindern wollen, dann müssen Sie eine lwsync oder Sync-Befehl oder eine gleichwertige Hochebene (C ++ 11?) Speichersperre.

behauptet, dass es „keine Möglichkeit, dass der Compiler die Dinge auf problematische Weise Neuordnen“ als allgemeine Aussagen naiv erscheinen, weil Compiler-Optimierungen ziemlich überraschend sein kann und weil CPUs (PowerPC / ARM / Alpha / MIPS insbesondere) aggressiv Neuordnungsspeicheroperationen .

Ein kohärenter Cache nicht speichern Sie entweder. Siehe http://preshing.com/ zu sehen, wie Speicher-Neuordnungs wirklich funktioniert.

In diesem Fall jedoch, glaube ich, die Antwort ist, dass keine Hindernisse erforderlich sind. Das ist, weil für diesen speziellen Fall (Referenzzählung) gibt es keine Notwendigkeit für eine Beziehung zwischen dem Referenzbild und den anderen Werten in dem Objekt. Die einzige Ausnahme ist, wenn der Referenzzähler trifft Null. An diesem Punkt ist es wichtig, sicherzustellen, dass alle Aktualisierungen von anderen Threads zu dem aktuellen Thread sichtbar sind so eine Lese-acquire Barriere kann notwendig sein.

Beabsichtigen Sie Ihre eigenen atomic_dec zu implementieren oder fragen Sie sich nur, ob ein System bereitgestellte Funktion verhält sich, wie Sie wollen?

Als allgemeine Regel vom System bereitgestellte Atom Erhöhen / Verringern Einrichtungen gelten, was Speicherbarrieren erforderlich sind, um das Richtige zu tun. Sie haben in der Regel nicht zu befürchten Speicher Barrieren, wenn Sie etwas verrückte tun, wie Sie Ihre eigenen Schloss freie Datenstrukturen implementieren oder eine STM-Bibliothek.

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