Heim >Backend-Entwicklung >C++ >Wie kann ich mithilfe von CAS einen sperrfreien ABA-Zähler in C 11 implementieren und den Leistungsaufwand minimieren?

Wie kann ich mithilfe von CAS einen sperrfreien ABA-Zähler in C 11 implementieren und den Leistungsaufwand minimieren?

Susan Sarandon
Susan SarandonOriginal
2024-12-15 08:07:11776Durchsuche

How can I implement a lock-free ABA counter in C  11 using CAS and minimize performance overhead?

Wie kann ich einen ABA-Zähler mit c 11 CAS implementieren?

Um zwei Werte gleichzeitig atomar zu aktualisieren, erstellen Sie eine atomare, benachbarte Struktur. Angenommen, Sie verwenden std::atomic um dies umzusetzen. Dann werden die folgenden Aktionen ausgeführt:

  1. Verwenden Sie die Sperranweisung cmpxchg16b auf x86-64-Prozessoren durch gcc-Kompilierung.
  2. Vermeiden Sie Inline-Assembly und bevorzugen Sie aus Effizienzgründen die C-Syntax.
  3. Setzen Sie Gewerkschaften ein, um ein effizientes Laden einzelner Strukturmitglieder zu ermöglichen.
  4. Stellen Sie 16B sicher (oder 8B für 32-Bit-Zeiger) Ausrichtung, um Leistungsprobleme auf x86-Architekturen zu verhindern.
  5. Verwenden Sie -mcx16 für x86-64-Builds, da cmpxchg16b von frühen x86-64-CPUs nicht durchgängig unterstützt wurde.

Beachten Sie, dass das atomare Objekt sperrenfrei sein sollte, insbesondere für x86-CPUs. Compiler wie gcc7 und höher rufen möglicherweise libatomic auf, anstatt die Inline-Sperre cmpxchg16b zu verwenden. Berücksichtigen Sie in solchen Szenarien Folgendes:

  • Stellen Sie sicher, dass der Compiler effizienten Code zum Lesen einzelner Mitglieder generiert, ohne auf eine Sperre cmpxchg16b des Paares zurückzugreifen.
  • Stellen Sie sicher, dass auf ein Gewerkschaftsmitglied zugegriffen wird Nach der Änderung ist ein anderes für die Implementierung klar definiert. Dies ist in GNU C zulässig, kann jedoch zu undefiniertem Verhalten führen, wenn Sie sich strikt an ISO C halten.
  • Stellen Sie sicher, dass das Objekt richtig ausgerichtet ist, da eine Fehlausrichtung auf x86-Architekturen zu Leistungseinbußen führen kann.
  • Behalten Sie die Ausrichtung für 32-Bit-Zeiger bei, da atomare Objekte, die größer als Zeiger sind, möglicherweise Sperren auf x86-64 verwenden CPUs.

Hier ist ein Beispiel für C 11-Code, der diese Eigenschaften aufweist:

#include <atomic>
#include <stdint.h>

using namespace std;

struct node {
  struct alignas(2*sizeof(node*)) counted_ptr {
    node *    ptr;
    uintptr_t count;  // use pointer-sized integers to avoid padding
  };

  // hack to allow reading just the pointer without lock-cmpxchg16b,
  // but still without any C++ data race
  struct counted_ptr_separate {
    atomic<node *>    ptr;
    atomic<uintptr_t> count_separate;  // var name emphasizes that accessing this way isn't atomic with ptr
  };

  static_assert(sizeof(atomic<counted_ptr>) == sizeof(counted_ptr_separate), "atomic<counted_ptr> isn't the same size as the separate version; union type-punning will be bogus");
  // TODO: write member functions to read next.ptr or read/write next_and_count

  union {  // anonymous union: the members are directly part of struct node
    alignas(2*sizeof(node*)) atomic<counted_ptr> next_and_count;
    counted_ptr_separate  next;
  };
};

Zusammenfassend lässt sich sagen, dass die gleichzeitige atomare Änderung zweier Werte sorgfältige Design-, Compiler-Überlegungen und Ausrichtungsoptimierungen erfordert . Wenn Sie diese Richtlinien befolgen, können Sie sperrenfreie ABA-Zähler in C 11 mit effizientem und korrektem Code implementieren.

Das obige ist der detaillierte Inhalt vonWie kann ich mithilfe von CAS einen sperrfreien ABA-Zähler in C 11 implementieren und den Leistungsaufwand minimieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn