Используйте конструктор вместо atomic.store (), когда атомарность в данный момент не требуется - PullRequest
0 голосов
/ 02 мая 2018

Я использую std::atomic для атомарности. Тем не менее, где-то в коде атомарность не нужна программной логике. В этом случае мне интересно, нормально ли это, как педантично, так и практически, использовать конструктор вместо store() в качестве оптимизации. Например,

// p.store(nullptr, std::memory_order_relaxed);
new(p) std::atomic<node*>(nullptr);

1 Ответ

0 голосов
/ 02 мая 2018

В соответствии со стандартом, работает ли это полностью, зависит от реализации std::atomic<T>. Если он не блокируется для этого T, то реализация, вероятно, просто хранит T. Если он не заблокирован, все становится сложнее, поскольку он может хранить mutex или что-то еще.

Дело в том, что вы не знаете , что std::atomic<T> хранит. Это важно, потому что, если он хранит const -квалифицированный объект или ссылочный тип, то повторное использование хранилища здесь вызовет проблемы. Конечно, можно использовать указатель, возвращаемый позицией- new, но если используется const или ссылочный тип, исходное имя объекта p не может .

Зачем std::atomic<T> хранить const или ссылочный тип? Кто знает; я хочу сказать, что поскольку его реализация не находится под вашим контролем, то педантично вы не можете знать , как ведет себя любая конкретная реализация.

Что касается "практически", то вряд ли это вызовет проблему. Особенно, если atomic<T> всегда без блокировки.

При этом "практически" также должно включать в себя некоторое представление о том, как другие пользователи будут интерпретировать этот код. Хотя люди, имеющие опыт повторного использования хранилища, смогут понять, что делает код, они, вероятно, будут озадачены , почему вы это делаете. Это означает, что вам нужно либо прикрепить комментарий к этой строке, либо создать (шаблон) функцию non_atomic_reset.

Также следует отметить, что std::shared_ptr использует атомные приращения / убывания для своего счетчика ссылок. Я говорю об этом, потому что нет std::single_threaded_shared_ptr, который не использует атомики, или специального конструктора, который не использует атомику. Так что даже в тех случаях, когда вы используете shared_ptr в чистом однопоточном коде, эти атомы все еще работают. Комитет по стандартам C ++ посчитал это разумным компромиссом.

Атомика не дешевая, но она не , которая стоит дороже (в большинстве случаев), что использование необычных механизмов, подобных этому, чтобы обойти хранилище атома, является хорошей идеей. Как всегда, профиль, чтобы увидеть, стоит ли обфускация кода.

...