Атомарное поведение унарных операторов приращения - PullRequest
0 голосов
/ 18 декабря 2018

Где-то я читал, что унарные операторы являются атомарными по своей природе, и поэтому их можно использовать как в многопоточной среде.Чтобы подтвердить то же самое, я написал две отдельные программы, в которых в

  1. я использовал переменную x и увеличивал при помощи унарного оператора ++ x
  2. Я использовал переменную x и увеличивал при помощи x =x + 1

Я сравнил разборку обеих программ и не нашел разницы.Пожалуйста, предоставьте ваш вклад по этому вопросу.

Ответы [ 9 ]

0 голосов
/ 18 декабря 2018

Вы не указали тип x.

  1. Если x является 32-битным целым числом, когда платформа 16 или 8-битная, операция 'x ++' определенно выполнит несколько операций
  2. x может быть даже не базовым типом, x может бытьэкземпляр класса, где оператор ++ делает гораздо более сложные вещи, чем просто увеличивает целое число
0 голосов
/ 18 декабря 2018

Атомарное поведение унарных операторов

В C до / после исправления ++ не унарные операторы , такие как & * + - ~ !.но часть унарного выражения .Таким образом, заголовок вопроса не согласуется с телом.

Даже унарный оператор, такой как +, не является атомарным, поскольку доступ к объекту (например, long long) заставляет принимать несколько операций чтения кода операции.

0 голосов
/ 18 декабря 2018

При написании кроссплатформенного C ++ у вас есть только атомарное поведение при использовании std::atomic<>.

Это правда, что на некоторых платформах, таких как Intel 64bit, процессор гарантирует, что inc является атомарным.Однако, пожалуйста, не пишите код, который зависит от этого!Как ваш будущий отладчик, я хотел бы знать, какие данные предназначены для совместного использования в потоках, а какие нет.

Использование std::atomic<int> может быть немного труднее написать, однако это гарантирует, что все ведет себя атомарно (на каждой платформе), либо отступая от требований к платформе ( std :: atomic:: is_lock_free ) или путем явной блокировки доступа.Он также вставляет защитные устройства, чтобы убедиться, что кэши других процессорных ядер признаны недействительными (если платформа требует этого).

На практике для Intel 64bit это должно дать вам ту же сборку, если нет, зарегистрируйте ошибку на своем компиляторе.

В то же время некоторые операции с целыми числами могут быть не атомарными (оператор * =), std::atomic просто не содержит этих операций, что требует правильной работы с ними.тех.

На заметку: ++x и x = x+1 - это разные операции, они могут быть оптимизированы для одной и той же сборки.Учитывая неатомарные требования к платформе, второй неожиданно становится ошибка, на решение которой уходят дни.

0 голосов
/ 18 декабря 2018

Вы делаете предположение о сгенерированном коде, если генерируется только одна инструкция, да, она будет атомарной, иначе нет.

В вашем случае это предполагает, что целевой процессор имеет инструкцию inc <address> и компиляторбудет производить его.

0 голосов
/ 18 декабря 2018

Атомность операции stronglr зависит от целевой системы.Унарная работа может не быть атомарной в системах RMW, таких как микроконтроллеры RISC.

Не существует единого общего ответа на этот вопрос.

0 голосов
/ 18 декабря 2018

Не верно.Даже если бы это было, какая причина была бы https://en.cppreference.com/w/cpp/atomic/atomic#Type_aliases тогда?

Я думаю, что они, вероятно, имели в виду, что вычисления для такой операции, как правило, очень малы и, следовательно, с высокой вероятностью никогда не будут иметь условия гонки, что в основном верно в живом коде, где вы не вычисляете x ++ в 4 для цикловодновременно.

0 голосов
/ 18 декабря 2018

Где-то я читал, что унарные операторы являются атомарными по своей природе, и поэтому их можно использовать как в многопоточной среде.

Это неверно.Например, x++ требует загрузки x, добавления и хранилища x.Эти инструкции не являются атомными по своей природе.

0 голосов
/ 18 декабря 2018

Утверждение, что унарный оператор обязательно является атомарным, является мифом.

Например, ++x требует чтения и записи в x, что открывает возможность гонки данных.

Тот факт, что ++x компилируется с тем же кодом, что и x = x + 1, не имеет значения.

Если вы хотите избежать гонок данных, используйте атомарные типы или единицы взаимного исключения, если подходящий атомарный типне доступен.Во избежание сомнений, int не обязательно атомарный тип.

0 голосов
/ 18 декабря 2018

Где-то я читал, что унарные операторы являются атомарными по своей природе, и поэтому их можно использовать как в многопоточной среде.

Этот источник совершенно неверен.Вам нужно использовать std::atomic (или эквивалент C) для достижения атомарности - унарные операции не являются специальными.


Я сравнил разборку обеих программ и не обнаружил различий

Это не значит, что сгенерированные операции являются атомарными.Разницы нет, так как любой приличный компилятор оптимизирует x=x+1 и ++x в одну сборку (при условии встроенных типов).

...