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

Десь я читав, що одинарні оператори по своїй природі є атомними і тому вони можуть бути використані як в багатонитковому середовищі. Щоб підтвердити те ж саме, я написав дві окремі програми, де в

  1. Я використовував змінну x і збільшувалася за допомогою унарного оператора ++ x
  2. Я використав змінну x і збільшився за допомогою x = x + 1

Я порівняв розбирання обох програм і не виявив ніякої різниці. Будь ласка, вкажіть ваші вклади щодо цього.

2
Ваші змінні атомні? Такі, як std :: atomic в C ++.
додано Автор Daniel Langr, джерело
Не має значення, чи є певна інструкція атомною, або ви маєте правильну синхронізацію або гонку.
додано Автор Baum mit Augen, джерело
Я підозрюю, що скрізь, де б ви не читали, використовувалося слово "atomic" в іншому сенсі, ніж слово, що використовується в контексті паралелізму. Або це, або вони були абсолютно неправі, і ви не повинні вірити тому, що ви там бачили.
додано Автор molbdnilo, джерело
Наступні дії: до того, як паралелізм був скрізь, не було рідко сказати, що префікс ++ "атомно збільшує змінну і повертає нове значення", але це "атомарний" означає, що він синтаксично - це лише одна операція - не те, що вона є неподільною.
додано Автор molbdnilo, джерело
Тільки тому, що ++ x є атомарним, це не означає, що x = x + 1 не є? (З логічної точки зору, я сумніваюся, що ++ x завжди атомний
додано Автор Ctx, джерело
З урахуванням змінної може перебувати в пам'яті і, отже, вимагати декількох інструкцій (завантаження, додавання, зберігання), вони не є автоматично атомарними
додано Автор Simon F, джерело

7 Відповіді

Десь я читав, що одинарні оператори є атомними за своєю природою і тому їх можна використовувати як в багатопотоковому середовищі.

That source is completely wrong. You need to use std::atomic (or the C equivalent) to achieve atomicity – unary operations are not special.


Я порівнював розбирання обох програм і не виявив різниці

Це не означає, що генеровані операції є атомними. Немає ніякої різниці, оскільки будь-який гідний компілятор оптимізує x = x + 1 до ++ x (припускаючи вбудовані типи).

8
додано

Твердження, що унарний оператор обов'язково є атомним, є міфом.

Наприклад, ++ x вимагає читання і запису в x , так що відкривається можливість гонки даних.

Той факт, що ++ x компілюється в тому ж коді, що і x = x + 1 , не є доречним.

Якщо ви хочете уникнути раси даних, то використовуйте атомарні типи, або взаємні виключення, якщо відповідний атомний тип недоступний. Щоб уникнути сумнівів, int не обов'язково є атомним типом.

3
додано
Ти єдина.
додано Автор Sombrero Chicken, джерело
Десь я читав, що одинарні оператори по природі атомні і тому вони   можна використовувати як у багатопотоковому середовищі.

Це помилково. x ++ , наприклад, вимагає завантаження x , додавання та сховища x . Ці вказівки не є атомними за своєю природою.

2
додано

Неправда. Навіть якщо це було б, то, чому причина буде https://en.cppreference.com/w/cpp/atomic/atomic # Type_aliases ?

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

1
додано

Атомність операції stronglr залежить від цільової системи. Одинарна операція не може бути атомною на системах RMW, таких як мікроконтролери RISC.

Немає жодного загального відповіді на це питання.

1
додано
Хороша відповідь (хоч і трохи лаконічна), оскільки вона не стверджує, що вона ніколи не може бути атомною (як це роблять інші). Але: існує "єдина загальна відповідь" на питання: "Ні, унарні оператори не атомні за природою ".
додано Автор Ctx, джерело

Ви робите припущення про згенерований код, якщо генерується тільки одна інструкція, то вона буде атомною, інакше ні.

In your case this supposes the target processor has the instruction inc

and the compiler will produce it.
0
додано

When writing cross platform C++, you only have atomic behavior when using std::atomic<>.

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

Using std::atomic might be a bit more work to write, however, it does guarantee that everything behaves atomically (on every platform) by either falling back to the platform requirements (std::atomic::is_lock_free), or by explicitly putting a lock around the access. It as well insert guards in order to make sure that the caches of the other processor cores are invalidated (if the platform requires this).

На практиці для Intel 64bit, це повинно дати вам ту ж саму збірку, якщо ні, зареєструйте помилку на вашому компіляторі.

У той же час деякі операції з ints не можуть бути атомними (оператор * =), std :: atomic просто не виконує ці операції, вимагаючи від вас коректної роботи з ними.

На бічній ноті: ++ x і x = x + 1 - різні операції, вони можуть бути оптимізовані для однієї збірки. Враховуючи неатомні вимоги до платформи, другий раптом - це помилка, яка вимагає днів для вирішення.

0
додано
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147