Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
1 / 1 / 0
Регистрация: 03.08.2017
Сообщений: 205

Имеет ли смысл создавать volatile переменную

16.09.2026, 11:08. Показов 13886. Ответов 171

Студворк — интернет-сервис помощи студентам
У меня есть функция
C++
1
2
void getParam(double &param){ //...
}
Вызов написал в таком виде:
C++
1
2
3
//...
{volatile double gain;
getParam((double&)gain);//...
Имеет ли смысл такая конструкция или лучше воспользоваться обычной переменной double?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.09.2026, 11:08
Ответы с готовыми решениями:

1 класс имеет переменную указатель на 2, 2 имеет на 1
Имеется 2 класса. В 1 классе есть переменная-указатель на 2 класс, а во 2 классе есть...

Применение описателя Volatile
Приведите плз пример простой проги с этим описателем а то я не пойму для чего он вообще нужен?В чём...

Пример использования спецификатора volatile
В приложенной картинке (из книги Г.С. Шилдта по C++) есть пример использования спецификатора...

171
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 849
23.09.2026, 16:37
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Recrut_rf Посмотреть сообщение
если принять на веру, что операции чтения и записи на платформе атомарны
Не надо принимать на веру. Надо изучить систему команд платформы, и сказать: "Для чтения или записи выровненной переменной типа int (или char или какого другого типа) компилятором могут быть использованы такие-то и такие-то команды.
Вот это аргументированный ответ. И никаких тайн ведь нет - любой может просмотреть систему команд.
Почему никто не пытается? Тогда ведь станет ясно, что на подавляющем большинстве платформ можно найти такие типы данных, операции чтения и записи для которых будут всегда атомарны.
Цитата Сообщение от Recrut_rf Посмотреть сообщение
Но только при тех условиях, которые вы сами перечислили - что в данной системе будут атомарные операции чтения и записи.
Именно так. А на другой платформе можно найти другие типы, для которых простые операции будут атомарны.
Операции присваивания с типом char насколько мне известно - на всех платформах атомарны. По-крайней мере я не помню ни одной, где они бы не были атомарны. Мой пример можно запросто на char volatile переделать. Заменив всего одно слово в одном месте.

Цитата Сообщение от Recrut_rf Посмотреть сообщение
используешь многопоток - применяй volatile ) А в саму суть нифига не вникает - потому что в потоках срача данной темы не щарящий мало что полезного для себя найдёт"
Я в самом начале написал:
Цитата Сообщение от jcxz Посмотреть сообщение
Зависит от содержимого getParam(). От того, как она внутри работает с gain.
Естественно - алгоритм должен быть адекватный.
И тут у некоторых теоретиков порвало пуканы. Они начали писать, что volatile вообще не нужен...
1
3 / 2 / 1
Регистрация: 21.09.2026
Сообщений: 35
23.09.2026, 17:06
Цитата Сообщение от jcxz Посмотреть сообщение
Не надо принимать на веру. Надо изучить систему команд платформы, и сказать: "Для чтения или записи выровненной переменной типа int (или char или какого другого типа) компилятором могут быть использованы такие-то и такие-то команды.
Вот это аргументированный ответ. И никаких тайн ведь нет - любой может просмотреть систему команд.
Спору нет, тут я Вас поддерживаю, но есть одно НО. Как справедливо было замечено выше, это раздел для начинающих. А им и сам С++ не всегда легко дается, а Вы им накидываете еще в нагрузку гору терминов, в которых-то и не новичок запутается. Гораздо проще сказать, что да, согласно стандарту volatile НЕ атомарен, а std::atomic<> атомарен всегда и везде. Но для volatile есть нюансы, зависящие от платформы. Все, коротко, ясно и не оставляет возможности для разночтения.
Цитата Сообщение от jcxz Посмотреть сообщение
Они начали писать, что volatile вообще не нужен...
Он нужен. Но использование его как гарантированно атомарного типа не корректно (с учетом текста выше).
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
23.09.2026, 18:08
Тут осталось лишь в 100500 раз вспомнить первые приходящие на ум попоболи всех этих "знатоков платформ" (где за их воображаемым "знанием платформы", разумеется, скрывается лишь лень изучать язык программирования) из обширной хронологии этих попоболей, которые мы имели возможность наблюдать, понимающе улыбаясь, за недавние десятилетия.

Что у нас там первое? Strict overflow semantics? "Знаковые типы всегда заворачиваются, как беззнаковые! Надо знать платформу! Приведи пример платформы!!1...", затем броуновское метание со столбами дыма из задниц, потешные столкновения лбами, вопли "Эти идиоты ничего не понимают! Я не буду пользоваться этим компилятором!! На мыло всех разработчиков!!!...", вмешательство санитаров, этап принятия.

"Можно возвращать указатели на локальные переменные! При выходе из функции данные просто остаются в стенке нетронутыми! Надо знать платформу! Приведи пример платформы!!1..." Компиляторы начинают наказывать рукопопых пионэров через ud2 или возврат нуля. Броуновское метание со столбами дыма из задниц, потешные столкновения лбами, вопли "Эти идиоты ничего не понимают! Я не будут пользоваться этим компилятором!! На мыло всех разработчиков!!!...", вмешательство санитаров, этап принятия.

Затем UB при попытках применять memcpy к перекрывающимся регионам, strict aliasing semantics, неинициализированные переменные, бесконечные циклы и т.д. и т.п... Далее, ну вы догадались: броуновское... лбами... этап принятия. И таких итераций - не счесть.

Но так как эта публика необучаема, ни один из этих этапов принятия, как вы сами понимаете, не является последним. Никаким объяснениями тут делу не поможешь. ¯\_(ツ)_/¯
6
 Аватар для Recrut_rf
391 / 336 / 66
Регистрация: 14.10.2014
Сообщений: 1,537
23.09.2026, 19:21
Полностью согласен с TheCalligrapher, если речь идёт о С++ и вопросы исключительно про С++, то не надо приплетать сюда внутреннее устройство той или иной платформы. Есть стандарт языка, он даёт определённые гарантии и если следовать этому стандарту - то будет ожидаемое и понятное всем, кто хоть немного знаком с С++, поведение. ПРИЧЁМ НА ВСЕХ ПЛАТФОРМАХ!!!!! Всё остальное - «От лукавого»

А ежели спросили - а как этот кусок кода можно оптимизировать или сделать так, чтоб он лучше работал. То милости просим - начинаем срач на тему "как оно там внутри устроено"
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 849
24.09.2026, 09:42
Цитата Сообщение от Recrut_rf Посмотреть сообщение
если речь идёт о С++ и вопросы исключительно про С++, то не надо приплетать сюда внутреннее устройство той или иной платформы. Есть стандарт языка
Стандарт языка у вас будет на CPU выполняться или всё-таки команды процессора данной платформы?

Не по теме:

Как правило - такие теоретики, типа персонажа выше, только на форумах умеют громогласно разглагольствовать. Когда дело доходит до реальной программы, вдруг оказывается что "Гениальный код почему-то глючит. Видимо компилятор виноват - плохо компилит." :D

0
 Аватар для Recrut_rf
391 / 336 / 66
Регистрация: 14.10.2014
Сообщений: 1,537
24.09.2026, 15:45
Цитата Сообщение от jcxz Посмотреть сообщение
Стандарт языка у вас будет на CPU выполняться или всё-таки команды процессора данной платформы?
Стандарт языка у меня будет выполнять компилятор, а уж какие он там команды процессора исполнять будет - мне вообще пофиг, в каком-то смысле, мне даже пофиг на архитектуру ARM, х86, х64 - да без разницы.
Меня интересует
- какую задачу мне поставили (какую программу нужно разработать и что она должна делать )
- под какую архитектуру - тут меня интересует наличие компилятора и нужных библиотек. Внутренним устройством вот вообще не заморачиваюсь, если только условия задачи этого требуют.
- какой стандарт языка можно использовать (бывают ограничения из-за платформы - допустим, она не поддерживает новейший стандарт, то есть для данной платформы тупо нет компилятора под современный стандарт языка. То, что это из-за того, что процессор на данной платформе не может выполнять какие-то команды - мне пофиг.... У меня задача совершенно другая и разрабатывать я буду на более высоком уровне - где мне не надо заморачиваться всеми этими командами.

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

Мне же, чаще всего, приходилось писать кроссплатформенный код и очень часто при помощи C++ Qt. И уж поверьте - знатоки архитектур, предлагающие на подобных проектах свои "мега оптимизации - мол вот это точно будет работать потому что .... (тут каждый знаток "железа" может вставить своё )" сразу шли далеко и на долго в известном направлении .
Наоборот, от нас очень часто требовали писать максимально простой, понятный, без всяких низкоуровневых приколов, код.

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

Я понял, что вы знаток архитектур и ассемблера. Хвала вам и почёт за это, без всякого сарказма. Сам я, ассемблер и прочие низкоуровневые вещи, если что - не знаю - как то не приходилось с ними сталкиваться. Но изучить, если время будет, хотя бы поверхностно - охота. За ваш пример - спасибо, обмозговал, подумал - узнал для себя некоторые новые вещи
НО НЕ НАДО ВСЕХ ГРЕСТИ ПОД ОДНУ ГРЕБЁНКУ!!!! И НЕ НАДО, УСЛОВНО, ВПАРИВАТЬ ВСЕМ СВОИ НИЗКОУРОВНЕВЫЕ АРХИТЕКТУРНЫЕ РЕШЕНИЯ.

Ваш пример интересен, но интерес его исключительно теоретический - заставляет подумать, поразмыслить. В абсолютном большинстве реальных проектов такое использовать НЕЛЬЗЯ, за такое будут БИТЬ ПО РУКАМ И ГНАТЬ ССАНЫМИ ТРЯПКАМИ, что аж пятки сверкать будут. Предположу, что есть крайне небольшое число реальных проектов, где подобное творчество будет использоваться. Но - там это либо действительно нужно будет (код очень сильно заточен под конкретное железо), либо кто-то, подобный вам, будет писать в одиночку. Вообще - если разработчик что-то сочиняет в одиночку, особенно упёртый на чём либо - уууух мать. Там такого можно будет увидеть....

Цитата Сообщение от jcxz Посмотреть сообщение
Гениальный код почему-то глючит
Если писать код согласно стандарту - ничего глючить не будет. Нато он и стандарт. Косяки разработчиков компиляторов не в счёт

И да - я не пытаюсь вас переубедить - я просто, развёрнуто ответил на ваш вопрос.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,220
Записей в блоге: 2
24.09.2026, 17:56
Еще вопросик. Потоку всегда надо как-то "выйти", поэтому часто пишется типа
C++
1
2
if (stopFlag) {
..
При этом флажок пишется одним потоком, обычно главным, а читается рабочими потоками. Возможны и др варианты. Так вот что с флажком?
Нужно объявлять его атомиком, (про себя) хуже не будет
И я сам поступлю так же. Но все-таки интересно, а почему? Ну вот stopFlag НЕ атомик, что мне за это будет? Практически это обычно сходит с рук, ну не увидел рабочий поток отмены, сделал еще итерацию, не беда, отмена сработает(?) чуть позже.

Хотелось бы услышать грамотное, пусть "академическое" объяснение. Спасибо
0
 Аватар для Recrut_rf
391 / 336 / 66
Регистрация: 14.10.2014
Сообщений: 1,537
24.09.2026, 18:20
Цитата Сообщение от Igor3D Посмотреть сообщение
Ну вот stopFlag НЕ атомик, что мне за это будет?
уважение и почёт и премия по итогам отлично проделанной работы


Мой ответ - может сложиться такая ситуация что один поток заканчивает читать stopFlag, в этот момент другой поток начинает изменять (писать в ) stopFlag. В результате можем получить ситуацию, что два разных потока прочитают одно и тоже значение. Либо один поток поломает значение для другого.

Если такая ситуация приемлема - то и нечего переживать, ну а чё оно....

Добавлено через 3 минуты
а атомик гарантирует предсказуемое поведение - без всяких доп приколов в виде - а чё падает... надцать лет работало и ничего, а тут вдруг.....
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
24.09.2026, 21:51
Цитата Сообщение от Igor3D Посмотреть сообщение
Ну вот stopFlag НЕ атомик, что мне за это будет?
будет неопределённое поведение.

например, поток может никогда не завершится
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
25.09.2026, 03:25
Конкуретный доступ к неатомарной переменной - неопределенное поведение (UB).

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

Если UB некоторого участка кода является условным, то компилятор имеет право полагать, что соответствующее условие всегда заведомо ложно. Если UB некоторого участка кода является безусловным, то компилятор имеет право полагать, что управление никогда не попадет в этот участок кода и его можно полностью выкинуть. И т.д. и т.п.

Мы здесь уже тысячи раз видели примеры того, как компиляторы это делают. И слушали сопутствующие попобольные вопли пионэров, имеющих странную манеру "транслировать" С/С++ код в машинные команды на основе собственных фантазийных домыслов, и почему-то ожидающих этого от компилятора.

Что касается кода, UB которого имеет место из-за того, что в нем выполняется конкурентный доступ к неатомарному объекту... понятно, что обнаружить такое UB через статический анализ кода трудно или даже невозможно. Так что не приходится ожидать, что компиляторы будут "наказывать" вас за такой овнокодинг в ближайшем будущем. (Хотя, с другой стороны, трудно предсказать, каких высот достигнут компиляторы в статическом анализе в средне-ближайшем будущем, учитывая возможности ИИ). Однако существенно более реалистичной причиной, по которой компиляторы сейчас не будут гоняться за оптимизациями через такой UB, является то, что она статистически незначительна: в реальной жизни никто просто так не делает. Даже среди пионэров-кулхацкеров нет такой манеры. Надо быть уж полным емелюшкой, чтобы использовать неатомарную переменную (volatile или нет - не важно) там, где можно просто написать std::atomic<> и получить во всех отношениях абсолютно тот же самый результат, но без UB.

Добавлено через 2 часа 1 минуту
---

Кстати, интересно также посмотреть как в С коде, генерируемом GCC и Clang, обрабатываются простые присваивания констант для _Atomic и volatile

C
1
2
3
4
5
6
7
8
_Atomic unsigned x;
volatile unsigned y;
 
int main() 
{
  x = 42;
  y = 42;
}
Assembler
1
2
3
4
5
6
7
8
9
10
"main":
        mov     eax, 42
        xchg    eax, DWORD PTR "x"[rip]
        xor     eax, eax
        mov     DWORD PTR "y"[rip], 42
        ret
"y":
        .zero   4
"x":
        .zero   4
Как видите, атомарная переменная присваивается через регистр и xchg (даже не mov). А volatile - через обычный mov с непосредственным операндом. Формально последняя - в целом не атомарная операция, но сам акт записи в память в ней по идее должен быть атомарным.

Мне навскидку не понятно, почему компиляторы настаивают именно на xchg.
1
3141 / 1742 / 274
Регистрация: 19.02.2010
Сообщений: 4,550
25.09.2026, 10:47
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Мне навскидку не понятно, почему компиляторы настаивают именно на xchg.
У Интела в его Software Developer’s Manual - Volume 2 - Instruction Set Reference для команды xchg написано английским по белому:
If a memory operand is referenced, the processor’s locking protocol is automatically implemented for the duration of the exchange operation, regardless of the presence or absence of the LOCK prefix
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 849
25.09.2026, 12:18
Цитата Сообщение от Igor3D Посмотреть сообщение
Ну вот stopFlag НЕ атомик, что мне за это будет?
Ничего не будет. А вот если не сделать stopFlag volatile-ом, то ваш поток может никогда не завершиться.

Добавлено через 1 минуту
Цитата Сообщение от Recrut_rf Посмотреть сообщение
В результате можем получить ситуацию, что два разных потока прочитают одно и тоже значение.
И что?
Вы в своих atomic-ах уже запутались.
Не нужен тут никакой atomic. Нужен volatile.

Добавлено через 10 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А volatile - через обычный mov с непосредственным операндом. Формально последняя - в целом не атомарная операция, но сам акт записи в память в ней по идее должен быть атомарным.
Наконец-то до вас дошло. То о чём я тут писал с начала темы.
Лучше поздно, чем никогда.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Мне навскидку не понятно, почему компиляторы настаивают именно на xchg.
Atomic-операции на x86 требуют RMW-команд с префиксом LOCK. Но данный префикс (насколько помню) - не может быть применён к команде MOV. Так как это не RMW-команда. Возможно поэтому - компилятор ставит XCHG, а потом "вспоминает", что сама операция операция записи в память внутри XCHG и так уже атомарна сама по себе. Так что - хоть MOV тут поставь, хоть XCHG - без разницы. Но компилятор уже поставил XCHG и её оставляет. Чтение и запись ПО ОТДЕЛЬНОСТИ - и так атомарны.
Это то, о чём я тут твердил с начала темы. И с чем вы (с кодлой приспешников) спорили с пеной у рта.

Добавлено через 6 минут
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
If a memory operand is referenced, the processor’s locking protocol is automatically implemented for the duration of the exchange operation, regardless of the presence or absence of the LOCK prefix
Ну или по этой формальной причине ставит XCHG, а не MOV. В любом случае - там без разницы какую команду поставить.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
25.09.2026, 17:53
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
У Интела в его Software Developer’s Manual - Volume 2 - Instruction Set Reference для команды xchg написано английским по белому:
If a memory operand is referenced, the processor’s locking protocol is automatically implemented for the duration of the exchange operation, regardless of the presence or absence of the LOCK prefix
Я об этом уже много раз писал выше.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Мне навскидку не понятно, почему компиляторы настаивают именно на xchg.
Однако, да, дело именно в этом. И GCCшники уже ответили, и на самом деле в ссылках на SO, которые я давал выше ответ уже содержится (https://stackoverflow.com/ques... y-use-xchg).

Я ошибочно полагал ("знал, но забыл"), что выровненный mov тоже содержит неявный lock. А это далеко не так. Инструкция mov гарантирует "монолитность" операции сохранения данных, однако не гарантирует требуемой когерентности памяти. Инструкция mov не генерирует полноценный барьер в памяти (как это делал бы префикс lock). Сохранение данных в память через mov имеет более слабую семантику: memory_order_seq_cst, то есть лишь release-semantics в случае записи в память. Чтобы получить полноценный барьер с mov, нужно еще прилепить за ней mfence. Но это будет уже менее эффективно, чем xchg.

С mov без mfence мы получаем memory_order_seq_cst, а это значит, что возможно вот такое развитие событий:

0. Две переменных x и y изначально равны 0
1. Два потока X и Y запускаются. Поток X делает только x = 1. Поток Y делает только y = 1.
2. Посторонние наблюдатели - потоки A, B, C ... - сначала видели в переменных x и y нули, затем они увидят как какая-то переменная первой получит значение 1, затем они увидят как обе получили значение 1.
3. Если потоки X и Y выполняют присваивание с memory_order_seq_cst (mov в volatile), то разные наблюдатели могут видеть разное развитие событий, т.е. какая переменная получила значение 1 первой: в переходный период некоторые потоки-наблюдатели могут видеть ситуацию x==1, y==0, а другие - ситуацию x==0, y==1.

Если работа с переменными идет с полноценным барьером (префикс lock, явный или неявный, т.е. xchg), то все наблюдатели будут видеть строго одно и то же, т.е. будут согласны в том, какая переменная получила значение 1 первой. Вот именно поэтому для атомарных переменных генерируется xchg. Никакой mov сам по себе тут работать не будет.

То есть, еще раз, инструкция mov гарантирует "монолитность" записи, но не дает требуемой для синхронизации когерентности памяти. То есть mov - это никогда не атомарная инструкция. Разумеется, никакой "синхронизации" вы через mov не получите. Так что, еще раз, унылый бред сивой кобылы от "знатоков платформ" о том, как они будут использовать volatile переменные для синхронизации, ценен только тем, что позволяет нам обратить внимание на вот такие вот детали. Но, как уже говорилось не раз, необучаемым все это можно дылдонить до бесконечности - все бесполезно.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
25.09.2026, 20:23
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
С mov без mfence мы получаем memory_order_seq_cst
Позвольте подправить, sequential-consistency как раз самая строгая модель памяти, предполагает single total order, а mov на х86 гарантирует только release семантику, т.е. может быть переупорядочена с последующими операциями, и не гарантирует single total order.

Что же касается volataile, то как уже много где разбиралось, если компилятор запрещает переупорядочивание вокруг нее и архитектура гарантирует aqcuire-release семантику (как x86), то она действительно может использоваться для синхронизации. Но там товарищ ранее упомянул ARM, не уточнив, что на ARM с weakly-ordered моделью памяти volatile обеспечивает только memory_oreder_relaxed семантику и уже не может использоваться для синхронизации (в привычном понимании этого слова). Правда непонятно, зачем заниматься хреновней, если есть std::atomic и std::memory_order на любой вкус.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
25.09.2026, 21:34
Цитата Сообщение от zayats80888 Посмотреть сообщение
Позвольте подправить, sequential-consistency как раз самая строгая модель памяти, предполагает single total order, а mov на х86 гарантирует только release семантику, т.е. может быть переупорядочена с последующими операциями, и не гарантирует single total order.
Да, спасибо, все верно. Я перепутал идентификаторы. memory_order_seq_cst - это наоборот, самая сильная гарантия, которую мы получаем от lock-операций, включая xchg. mov нам дает только memory_order_release.

Цитата Сообщение от zayats80888 Посмотреть сообщение
Что же касается volataile, то как уже много где разбиралось, если компилятор запрещает переупорядочивание вокруг нее и архитектура гарантирует aqcuire-release семантику (как x86), то она действительно может использоваться для синхронизации.
Может, но через грамотное использование свойств aquire-release семантики для тщательной реализации синхронизационных примитивов на основе соответствующих алгоритмов, а не через тупое ожидание готовой атомарности от mov прямо из коробки. Интеловский мануал содержит примеры того, как может вести себя именно mov. В частности пример, который разбирает Preshing вот здесь

https://preshing.com/20120515/... n-the-act/

(В современной версии интеловского мануала это глава 11, а не 8, как по ссылке)
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 849
26.09.2026, 13:20
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть mov - это никогда не атомарная инструкция. Разумеется, никакой "синхронизации" вы через mov не получите.
То есть, по вашей версии - MOV записывает значение в память побитно? Ибо только в таком случае будут проблемы с доступом к ней из разных потоков.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Так что, еще раз, унылый бред сивой кобылы от "знатоков платформ" о том, как они будут использовать volatile переменные для синхронизации, ценен только тем, что позволяет нам обратить внимание на вот такие вот детали. Но, как уже говорилось не раз, необучаемым все это можно дылдонить до бесконечности - все бесполезно.
И это мы слышим от "спецыалиста", считающего что MOV пишет в память по-битно.
Это почище того бреда, что вы несли про fabs() в другой теме.
Так бывает, когда тему, о которой пытаешься рассуждать, знаешь только теоретически. Из роликов в инете и подсказок ИИ.

Добавлено через 2 минуты
Цитата Сообщение от zayats80888 Посмотреть сообщение
Но там товарищ ранее упомянул ARM, не уточнив, что на ARM с weakly-ordered моделью памяти volatile обеспечивает только memory_oreder_relaxed семантику и уже не может использоваться для синхронизации (в привычном понимании этого слова).
Тогда поясните - как по вашему на ARM данные должны записываться в память? Побитно???
Думаете - сперва один процесс/задача пишет один бит, потом следующая задача - следующий бит т.д.? Или как?

Вот допустим - есть команда: STRB Rx,[Ry] и похожая команда STRB, выполняющаяся в другом потоке (или даже другим ядром). И есть байтовая переменная, используемая для синхронизации. Расскажите в каком именно случае при записи возникнет проблема?

Добавлено через 8 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Может, но через грамотное использование свойств aquire-release семантики для тщательной реализации синхронизационных примитивов на основе соответствующих алгоритмов
Опять пустой поток слов, без какого-либо представления о реальной работе реальных систем. Опять диванное теоретизирование по вычитанному в инетике...
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
26.09.2026, 14:25
Цитата Сообщение от jcxz Посмотреть сообщение
Тогда поясните - как по вашему на ARM данные должны записываться в память? Побитно???
Думаете - сперва один процесс/задача пишет один бит, потом следующая задача - следующий бит т.д.? Или как?
При чем тут какое-то "побитно"? Мне кажется вы путаете атомарность и синхронизацию. Не все атомарные операции являются синхронизирующимим. Не достаточно прочитать значение, записанное другим потоком в атомарный тип, часто нужно еще получить гарантии увидеть тот же (или частично тот же) порядок модификации другой памяти. В контексте приведенного вами примера, если, например, в первом акте программисту прострелили голову за говнокод, то когда его будут хоронить во втором акте, может оказаться что он еще жив (на архитектурах с weakly-ordered memory model).
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
26.09.2026, 17:51
Цитата Сообщение от zayats80888 Посмотреть сообщение
Мне кажется вы путаете атомарность и синхронизацию.
Он не понимает разницы между гарантиями, который дает термин "атомарность" из аппаратного мануала, и гарантиями которые дают встроенные операции языка над атомарными типами в С/С++. (Отсюда и странные бредни про "побитовую запись" выше.)

1. В аппаратных мануалах атомарные операции - это всего лишь монолитные/неделимые операции. Такие операции гарантируют, что никакой внешний наблюдатель не увидит "рваных" данных, то есть не увидит операцию сделанной наполовину. Все.

2. С и С++ на встроенные операции над атомарными объектами накладываются дополнительные требования - это вышеупомянутая монолитность плюс требование того, чтобы при работе с такими атомарными объектами через встроенные операторы использовался memory_order_seq_cst (6.2.6.1/9, 6.5.16.2/3, 6.5.2.4/2 и т.п.). В С и С++ такие операции гарантируют не только то, что внешний наблюдатель не увидит операцию сделанной наполовину, но то что все внешние наблюдатели видят один и тот же глобальный порядок изменения данных.

xchg сответствует С/С++ требованиям атомарности, mov - не соответствует.

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

---

Кстати, раньше не удосуживался разглядывать, а сейчас обратил внимание: в случае, когда готовой атомарной операции нет, компилятор генерирует полноценный CAS-цикл

C
1
2
_Atomic unsigned long long x = 42;
int main() { x *= 25; }
Assembler
1
2
3
4
5
6
7
8
9
10
11
main:
        mov     rax, QWORD PTR x[rip]
.L2:
        lea     rdx, [rax+rax*4]
        lea     rdx, [rdx+rdx*4]
        lock cmpxchg    QWORD PTR x[rip], rdx
        jne     .L2
        xor     eax, eax
        ret
x:
        .quad   42
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 849
26.09.2026, 20:22
Цитата Сообщение от zayats80888 Посмотреть сообщение
При чем тут какое-то "побитно"?
А как же ещё одна запись переменной может помешать другой записи этой же самой переменной в пределах одного процесса, но в другом его потоке? Или чтению.

Добавлено через 2 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В аппаратных мануалах атомарные операции - это всего лишь монолитные/неделимые операции. Такие операции гарантируют, что никакой внешний наблюдатель не увидит "рваных" данных, то есть не увидит операцию сделанной наполовину. Все.
И как же эта самая операция может быть "сделана наполовину"?
Т.е. - биты с 0-го по 3-й - записались, а с 4-го по 31-й - ещё не записались?
Это на какой архитектуре такое по вашему может произойти? На x86? на ARM? ...?

Добавлено через 2 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
xchg сответствует С/С++ требованиям атомарности, mov - не соответствует.
Т.е. - по вашему - MOV пишет биты в память (и читает из памяти) по-битно???
И поэтому может пересечься с другой MOV, направленной в ту же переменную в другом потоке???
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
26.09.2026, 20:28

Не по теме:

Цитата Сообщение от jcxz Посмотреть сообщение
И как же эта самая операция может быть "сделана наполовину"?
Т.е. - биты с 0-го по 3-й - записались, а с 4-го по 31-й - ещё не записались?
Это на какой архитектуре такое по вашему может произойти? На x86? на ARM? ...?
Тут по-моему всё уже совсем плохенько, народ. Ему открытым текстом черным по белому пишут, что частичной записи быть не может, а ему мерещится какие-то "биты с 0-го по 3-й - записались, а с 4-го по 31-й - ещё не записались"... Мне кажется, мы его теряем.

Или это уже совсем ЖЫРНЫЙ флудинг пошел?



Мне действительно интересно - может я уже теряю связь с какими-то скрытыми смыслами в русском языке. Обращаясь к участникам форума: в цитате

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
1. В аппаратных мануалах атомарные операции - это всего лишь монолитные/неделимые операции. Такие операции гарантируют, что никакой внешний наблюдатель не увидит "рваных" данных, то есть не увидит операцию сделанной наполовину. Все.
хоть один человек сможет усмотреть возможность "биты с 0-го по 3-й - записались, а с 4-го по 31-й - ещё не записались"? Или все таки в цитате выше ясно говорится, что такого быть не может?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.09.2026, 20:28

const volatile
Пример из Шилдт Г. &quot;С++ Базовый курс (3-е издание, 2010)&quot; стр 205 const volatile unsigned char...

исследование volatile
Здравствуйте. В университете дали задание: &quot;Исследование квалификаторов volatile и инструкции...

int\ volatile int \ const int
Товарищи, паника! Имеется код: int a = 5; std::cout &lt;&lt; &quot;Init value a: &quot; &lt;&lt; a &lt;&lt; &quot;\n&quot;; ...

const_cast: const и volatile
Как известно const_cast сбрасывает наложенные ограничения при помощи модификаторов const и...

Что такое "volatile int"
есть объявление и инициализация переменной: volatile int Sklad = 0; что такое &quot;volatile&quot;? с msdn...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru