Нужно ли загружать и хранить барьеры памяти (заборы), или достаточно барьера магазина?

у меня есть std::atomic<int>* key, *val;

Я хочу написать обоим. Есть несколько потоков, читающих эти значения одновременно. Я хочу убедиться, что val написан перед ключом. Это гарантирует, что если читатели увидят новое значение ключа, они ДОЛЖНЫ также увидеть новое значение val. Хорошо видеть новый val со старым ключом или видеть оба старых значения. Код должен работать на расслабленной процессорной архитектуре (ARM).

Обычно этого достаточно сделать (по порядку) val->store(x, relaxed), key->store(y, release) и загрузить их (по порядку) key->load(acquire), val-load(relaxed), На ARM, я полагаю, приобретает вставки барьера нагрузки и выпускает вставки барьера магазина. Однако по разным причинам я не использую атомарный для чтения val, и использование барьера для каждого доступа на чтение было бы слишком дорого.

Можно ли использовать только барьер магазина (sfence на x86) между двумя магазинами для обеспечения порядка? Помните, что видеть устаревшие значения для ключа и val очень хорошо, все, что я хочу убедиться, что если новое значение для ключа увидит другое ядро, оно также должно увидеть новое значение val. Читатель всегда сначала читает ключ, а чтение val зависит от значения ключа (даже если это адрес памяти), поэтому я не верю, что компилятор или процессор могут переупорядочить нагрузки так, чтобы val был прочитайте перед ключом. Это должно было бы прочитать ключ, чтобы даже знать, где искать val. Я подозреваю, что именно это свойство позволяет коду работать без барьера загрузки.

Я прав?

5

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]