Melaksanakan Pembilang Atom 64-bit dengan Pembolehubah Atom 32-bit
Soalan:
Reka bentuk dan laksanakan pembilang atom 64-bit menggunakan atom 32-bit pembolehubah. Kaunter mempunyai seorang penulis (pengendali isyarat) dan berbilang pembaca.
Kod:
class counter { atomic<uint32_t> lo_{}; atomic<uint32_t> hi_{}; atomic<uint32_t> gen_{}; uint64_t read() const { auto acquire = memory_order_acquire; uint32_t lo, hi, gen1, gen2; do { gen1 = gen_.load(acquire); lo = lo_.load(acquire); hi = hi_.load(acquire); gen2 = gen_.load(acquire); } while (gen1 != gen2 || (gen1 & 1)); return (uint64_t(hi) << 32) | lo; } void increment() { auto release = memory_order_release; gen_.fetch_add(1, release); uint32_t newlo = 1 + lo_.fetch_add(1, release); if (newlo == 0) { hi_.fetch_add(1, release); } gen_.fetch_add(1, release); } };
Jawapan:
Kod yang disediakan ialah pelaksanaan yang betul bagi pembilang atom 64-bit menggunakan pembolehubah atom 32-bit. Ia menggunakan teknik yang dikenali sebagai SeqLock, yang menggunakan kiraan penjanaan untuk mengekalkan konsistensi bahagian tinggi dan rendah pembilang.
Operasi baca menggunakan gelung untuk memperoleh keadaan pembilang yang betul semasa mengendalikan keadaan perlumbaan yang berpotensi antara pembaca dan penulis. Operasi tulis menambah kedua-dua bahagian tinggi dan rendah pembilang secara atom, menggunakan susunan memori untuk memastikan kelakuan yang betul.
Pelaksanaan yang Diperbaiki:
Sementara kod yang disediakan adalah betul , ia boleh dipertingkatkan untuk prestasi dan kecekapan yang lebih baik:
Reka Bentuk Alternatif:
Reka bentuk alternatif yang menghapuskan keperluan untuk operasi RMW atom sama sekali ialah menggunakan gabungan uint64_t yang tidak menentu dan std::atomic Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Pembilang Atom 64-bit Hanya Menggunakan Pembolehubah Atom 32-bit?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!