Aleksander
Constantine
Aidar
Aidar
Какая неважно
Aidar
Хотя изменение bool не обязательно атомарно
Anatoly
🐙 Antony
А так можно было? :)
Нет, так нельзя: компилятор вправе делать оптимизации не атомарных переменных из рассчёта, что они не используется в других потоках. Поэтому он например может выкинуть запись в эту переменную значения к чёртовой бабушке. А еще он может закешировать значение переменной и никогда его не обновлять
🐙 Antony
* ну и разумеется санитайзеры будут ругаться на не атомарную работу с одной переменной из многих потоков
Anatoly
Черт, как бы сделать так, чтобы сарказм не надо было пояснять :)
🐙 Antony
** ну и разумеется, всё это будет работать и без атомарных инструкций и атомиков. Но есть гарантия, что оно сломается в самый неподходящий момент
Вячеслав
Табличка "сарказм" нужна
🐙 Antony
Arseny
Вообще многие UB на практике проблемам не приводят.
До тех пор пока не приводят наконец. И тогда больно.
🐙 Antony
Если только bool, то не вижу смысла заморачиваться
atomic<bool> b;
...
b.store(true, memory_order_relaxed); // та же ассемблерная инструкция на x86 что и просто запись в неатомарную переменную, но компилятору запрещено чудить. Учтите, что memory_order_relaxed (как и запись в неатомарную переменную) не гарантирует "мгновенное" появление значения в другом потоке. Поэтому лучше писать:
b = true; // и никаких сюрпризов
Arseny
Berkus
Berkus
все что сделано до release обязательно появится в момент acquire
Andrey
Вопрос был про чтение bool
Andrey
Запись под мутексом
Arseny
Andrey
Атомика нет
Andrey
Вопрос нужно ли лочить мутекс чтобы прочитать значение
Arseny
vladislav
А в чём сложности тогда? Если нет атомика, то ты должен гарантировать корректность работы объекта класса между потоками, используя мутексы
vladislav
Да, нужно лочить мутекс
Andrey
Поглядел ассемблер с разными флагами оптимизации, там только мув. Разве мув не атомарный?
Cuno
Читай что тебе пишут, что ли.
Cuno
atomic<bool> b;
...
b.store(true, memory_order_relaxed); // та же ассемблерная инструкция на x86 что и просто запись в неатомарную переменную, но компилятору запрещено чудить. Учтите, что memory_order_relaxed (как и запись в неатомарную переменную) не гарантирует "мгновенное" появление значения в другом потоке. Поэтому лучше писать:
b = true; // и никаких сюрпризов
Andrey
Andrey
Когда строчка 63 выполнится?
Andrey
Что должно быть в rax?
Berkus
Berkus
Berkus
Konstantin
вроде даже на одном может быть не атомарный, если адрес не выровнен
Good
Cuno
мув атомарный НА ОДНОМ ЯДРЕ
Разве? Если одно ядро сделает mov dword ptr [addr], 1, затем другое mov eax, [addr] то разве может быть не 1 в rax?
Good
в пределах правильно выровненного слова
Berkus
Cuno
Berkus
Good
да даже если кеши отключены, чтение может зареордериться перед записью
Good
я немного про другое, это единственный реордеринг, возможный на х86, так что даже без кешей может сработать не так, как хотелось
Good
по идее, даже на одном цпу
Arseny
Кроме барьеров процессора ещё есть барьеры компилятора. И даже если процессор гарантирует release aquire семантику, без атомиков компилятор может все переставить и испортить
Arseny
Berkus
Aliaksei
Good
да, но что значит "same"? Если мы поиграемся с меппингом и получим два разных виртуальных адреса, указывающих на один физический, то что будет? Поэтому я и написал "по идее"
Good
Потому что запись в память на х86_64 имеет release семантику
Cuno
Разве? Если одно ядро сделает mov dword ptr [addr], 1, затем другое mov eax, [addr] то разве может быть не 1 в rax?
Good
хмм, данный вопрос не имеет особого смысла, ибо на одной переменной не показать реордеринг. Проще говоря, может быть и так и так, и подобной гарантии дать нельзя (в мультипроцессорной системе)
Cuno
Противоречиво
Good
В самом деле, если мы физически прочитали раньше, то мы должны прочитать 0, так? А как отличить в программе, почему мы прочитали 0 - из-за процессоров, подсистемы памяти или потому что тупо прочитали раньше (до записи)?
Good
Но, если эта единичка - флаг, который сигнализирует о готовности других данных, например, тогда другое дело
Good
Но тогда надо ввести как минимум еще одну переменную (те самые данны). Поэтому в интеловском мануале все примеры, как минимум, с двумя вариаблами
Cuno
Cuno
запись происходит строго раньше, чем чтение
Good
Это проверить невозможно, значит, программа на это полагаться не должна
Cuno
ААААААА
Cuno
на гарантии стандарта полагаться нельзя?
Berkus
причем тут стандарт?
Good
стандарт говорит про предыдущие и последующие записи-чтения, т.е. см выше про 2 и более переменные
Good
предыдущие записи были видны, когда будет видна эта запись
Good
а тут нет предыдущих, поэтому неважно, что мы прочтем - все и так и так ок будет
Good
Правильно будет так: https://godbolt.org/g/r9zuxz
Good
Тут тоже ничего такого нет, ибо х86 довольно strong-ordered, а вот если мы глянем на ppc (https://godbolt.org/g/9YpkiL), то увидим lwsync при сохранении (для порядка данных) и isync при загрузке (для порядка инструкций)
Berkus
Matwey
Ой, это же гудя
Matwey
@godstuff