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

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

16.09.2026, 11:08. Показов 13581. Ответов 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
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 19:27
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от jcxz Посмотреть сообщение
На x86 есть множество команд типа: память-непосредственный операнд.
Типа: ADD [EDI],5 и других подобных. См.систему команд x86.
Да, про "память - непосредственный операнд" я ляпнул мимо кассы. Такие инструкции есть. Но нам в рамках рассматриваемого примера нам нужны были операции "память - память".
0
20.09.2026, 19:30

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
я ляпнул мимо кассы
или это твой ИИ-помощник галлюцинировал? только скажи честно

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

для меня ты всегда ассоциировался с человеком, который 7 раз прочтет стандарт С++ и только потом ответит. Т.е. я знал, что написанным тобой утверждениям можно верить и ничего не проверять. Чёт не в твоем стиле, что-то ляпнуть. Эх, сдаешь позиции.

0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 19:40
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Да, про "память - непосредственный операнд" я ляпнул мимо кассы. Такие инструкции есть. Но нам в рамках рассматриваемого примера нам нужны были операции "память - память".
Такие тоже есть: Команды PUSH [EDI], POP [EDI] - что сразу в голову пришло, ну и все команды сохранения/восстановления в стек ячейки памяти.
Хотя для синхронизации потоков они наверное малополезны.
Лучше откройте систему команд x86 - я уже не очень хорошо её помню.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 19:46
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Почему? Зачем все время перечитывать значение ссылки в цикле в первом варианте? Просто косяк оптимизатора-кодогенератора? Или я упускаю какие-то более веские причины?
А, догадываюсь.... Любая атомарная операция расценивается как барьер в памяти. То есть тупо считается, что перевычитывать нужно вообще все. И действительно, если сделать

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::atomic<size_t> N{};
std::atomic<size_t> *const p = &N;
std::atomic<size_t> *const *const pp = &p;
std::atomic<size_t> *const *const *const ppp = &pp;
 
std::thread t1([&ppp]
{
  for(size_t i=0; i<steps; ++i)
  {
    ++***ppp;
    ++***ppp;
    ++***ppp;
  }
});
то инкременты будут выглядеть как

Assembler
1
2
3
4
5
6
7
8
9
10
11
     mov rdx, QWORD PTR [rdi+8]
     mov rdx, QWORD PTR [rdx]
     mov rdx, QWORD PTR [rdx]
     mov rdx, QWORD PTR [rdx]
lock add QWORD PTR [rdx], 1
     mov rdx, QWORD PTR [rdi+8]
     mov rdx, QWORD PTR [rdx]
     mov rdx, QWORD PTR [rdx]
     mov rdx, QWORD PTR [rdx]
lock add QWORD PTR [rdx], 1
...
Чтобы получить эффективный код придется возиться с барьерами вручную...


Добавлено через 4 минуты
Цитата Сообщение от jcxz Посмотреть сообщение
Такие тоже есть: Команды PUSH [EDI], POP [EDI] - что сразу в голову пришло, ну и все команды сохранения/восстановления в стек ячейки памяти.
Ну это не считается. Таких много можно найти.

Не надо притворяться, что вы не понимаете, о чем шла речь. Речь шла о копировании значения одной пользовательской переменной в другую пользовательскую переменную без использования промежуточного хранилища, каким бы оно ни было. Использование стека в качестве промежуточного хранилища ничем не лучше использования регистра в качестве промежуточного хранилища.
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 20:04
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну это не считается. Таких много можно найти.
Почему "не считается"? Они разве не "память-память" как вы просили?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Не надо притворяться, что вы не понимаете, о чем шла речь. Речь шла о копировании значения одной пользовательской переменной в другую пользовательскую переменную без использования промежуточного хранилища
Я не притворяюсь, я действительно не понимаю - какое отношение команды "память-память" имеют к volatile переменным? И зачем нужно копирование "одной пользовательской переменной в другую пользовательскую переменную" для синхронизации потоков основанной только на volatile-переменных?
Я выше привёл пример кода реализующего такую синхронизацию. Где и зачем там нужны операции "память-память"?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 20:11

Не по теме:


Цитата Сообщение от Royal_X Посмотреть сообщение
или это твой ИИ-помощник галлюцинировал? только скажи честно
Подобная уныла бредятина еще кому-то не набила оскомину?

Цитата Сообщение от Royal_X Посмотреть сообщение
в разделе низкоуровневого программирования я тебе никогда не видел. Сейчас же, когда появился ИИ, ты активно ассемблерными кодами кидаешься...
Я - один, разделов - много... Ассемблерными кодами я "кидался" всегда, тем и известен. Собственно, вышеупомянутый "раздел низкоуровневого программирования" на форуме было создан моими фанатами как место для коллекционирования, конспектирования, разборки и обсуждения моих "ассемблерных" постов здесь. Другими словами, низкоуровневое программирование - это всё мои ученики, но уже, по-видимому, произошла смена поколений, т.е. на смену ученикам пришли ученики учеников, ученики учеников учеников и т.д... В результате новая поросль стала забывать свои корни. А фигура отца-сенсея приобрела статус легендарной и мифической, в реальное существование которой уже почти не верят.

Цитата Сообщение от Royal_X Посмотреть сообщение
Т.е. я знал, что написанным тобой утверждениям можно верить и ничего не проверять. Чёт не в твоем стиле, что-то ляпнуть. Эх, сдаешь позиции.
Я известен не только благодаря своему авторитету в области низкоуровневого программирования, но и умением быстро распознавать/признавать/исправлять свои ошибочные утверждения.



Добавлено через 2 минуты
Цитата Сообщение от jcxz Посмотреть сообщение
Почему "не считается"? Они разве не "память-память" как вы просили?
Не надо притворяться непонимающим, о чем идет речь, и генерировать бессмысленные посты. Я не просил "память-память", я просил "указанная пользователем память - указанная пользователем память". Это было мгновенно кристально понятно с моего первого поста на эту тему.
0
20.09.2026, 20:23

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Я - один, разделов - много... Ассемблерными кодами я "кидался" всегда, тем и известен. Собственно, вышеупомянутый "раздел низкоуровневого программирования" на форуме было создан моими фанатами как место для коллекционирования, конспектирования, разборки и обсуждения моих "ассемблерных" постов здесь. Другими словами, низкоуровневое программирование - это всё мои ученики, но уже, по-видимому, произошла смена поколений, т.е. на смену ученикам пришли ученики учеников, ученики учеников учеников и т.д... В результате новая поросль стала забывать свои корни. А фигура отца-сенсея приобрела статус легендарной и мифической, в реальное существование которой уже почти не верят.
Скучно. Лучше пойду еще раз прочту древнегреческий миф о Нарциссе.

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
21.09.2026, 00:48

Не по теме:

Цитата Сообщение от Royal_X Посмотреть сообщение
Скучно. Лучше пойду еще раз прочту древнегреческий миф о Нарциссе.
Куда уж скучнее. Унылое трололо уныло...



Добавлено через 11 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Чтобы получить эффективный код придется возиться с барьерами вручную...
Нет, достаточно просто "кэшировать" значение захваченной ссылки в локальную ссылку

C++
1
2
3
4
5
6
7
8
9
10
std::thread t1([&N]
{
  auto &r = N;
  for(size_t i=0; i<steps; ++i)
  {
    ++r;
    ++r;
    ++r;
  }
});
и ненужные перечитывания пропадают, то есть в этом варианте один раз перед циклом делается

Assembler
1
mov rax, QWORD PTR [rdi+8]
а затем в цикле

Assembler
1
2
3
lock add QWORD PTR [rax], 1
lock add QWORD PTR [rax], 1
...
То есть старая добрая привычка не забывать вручную "кэшировать в локальные переменные" не теряет своей ценности. В С несколько помогает restrict, а в С++ все по-старому.

Добавлено через 4 часа 11 минут

Не по теме:

Цитата Сообщение от jcxz Посмотреть сообщение
Я не притворяюсь, я действительно не понимаю - какое отношение команды "память-память" имеют к volatile переменным
Перечитайте соответствующие сообщения в дискуссии еще раз - и все станет понятно. Специально для вас небольшой дайджест:

1. В сообщении #22 вы говорите, что volatile переменная не будет копироваться в регистр.
2. В сообщении #23 пользователь Алексей1153 в качестве возражения приводит пример кода, в котором volatile переменные загружаются в регистры.
3. В сообщении #24 я выступаю в вашу поддержку: я замечаю пользователю Алексей1153, что данная загрузка в регистр - это не замена/кэширование переменной в регистр, очевидно подразумевавшаяся вами в посте #22, а сиюминутная промежуточная загрузка, необходимая лишь потому, что в системе команд x86 нет команд "память - память" (т.е. команд "пользовательская переменная - пользовательская переменная").
4. Вы соглашаетесь с этим в посте #27
5. При этом в том же посте #27 и далее вы непонятно зачем начинаете разводить посторонний флуд о том, что команды "память - память" в системе команд x86 есть, форся какие-то примеры команд, которые никак не относятся к исходной ситуации из поста #22.
6. И в конечном итоге вы, кажется, вообще потеряли нить и забыли, о чем шла речь, что видно из вашей цитаты выше.

Что это? К чему здесь этот флуд? ¯\_(ツ)_/¯

1
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
21.09.2026, 00:57
Цитата Сообщение от jcxz Посмотреть сообщение
При чём тут атомарность и гонки если речь идёт о volatile? Какое отношение к теме имеет пример о неких гонках, если речь про volatile?
Ну Вы же говорили
Цитата Сообщение от jcxz Посмотреть сообщение
Объявление переменной volatile может быть вполне достаточно для некоторых способов межпоточной синхронизации.
А товарищ Вам доказывает что volatile не обеспечивает того же ф-ционала что atomic. Вполне "в тему".
Цитата Сообщение от jcxz Посмотреть сообщение
Изучите пример, что я привёл. Он не требует "atomic compare exchange" и нормально работает. Даже если потоки на разных ядрах.
Не уверен что Ваш пример - то что нужно изучать Он ужасно корявый. Ну да ладно, наша тема volatile. Верю что подобный код "всю жизнь работает", а может даже на каком-то компиляторе volatile необходим. Но по классике
Тестирование может показать наличие багов но не их отсутствие
Т.е. строго доказать что пример верен невозможно (таковы законы логики, это не Ваша вина). В такой ситуации лучше следовать правилам/стандарту (как убедил меня Заяц). Так вот (пусть поправят меня гуру) с точки зрения стандарта правильность Вашего примера не гарантируется. Поток всегда верно прочтет то что записал он сам ("видит" себя) но вот то что писали другие потоки - не гарантируется. Раньше это поясняли, мол, "кеши процессора(ов)", потом барьеры и все такое. Ну и за каким <T> искать приключений с volatile если есть прекрасный, причем штатный, способ std::atomic_int? Достаточно заменить объявление - и все дела

Не по теме:

И вот что

Цитата Сообщение от jcxz Посмотреть сообщение
Вы тоже не читатель а писатель?
Ещё раз..
Отвечать такому резвому (или борзому) собеседнику не хочется

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
21.09.2026, 01:39
Цитата Сообщение от jcxz Посмотреть сообщение
Изучите пример, что я привёл. Он не требует "atomic compare exchange" и нормально работает. Даже если потоки на разных ядрах.
Этот пример "работает" потому, что подогнан под аппаратные особенности конкретной платформы: то, что на x86 выровненные команды записи/чтения памяти являются неявно атомарными, то есть не требуют явного префикса lock для атомарности. А для случая нескольких ядер все еще держится на дополнительных гарантиях платформы x86 на тему когерентности памяти.

Однако все это не имеет никакого отношения к С++. И, что важно, никаких преимуществ перед штатными средствами организации атомарного доступа не предоставляет, особенно если учесть тонкости оптимизации доступа, описанные мною выше.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
21.09.2026, 03:29
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Этот пример "работает" потому, что подогнан под аппаратные особенности конкретной платформы: то, что на x86 выровненные команды записи/чтения памяти являются неявно атомарными, то есть не требуют явного префикса lock для атомарности. А для случая нескольких ядер все еще держится на дополнительных гарантиях платформы x86 на тему когерентности памяти.
Не все понял. Наверно имелось ввиду "atomistic" как его называет std. То есть если пишется напр int, то запишутся все 4 байта, не будет такого что 2 байта старых 2 новых. Важно что адрес должен быть выровнен. Но разве это уже атомарность? И с ядрами/когерентностью не уловил

Да, и вот хороший вопросик. Есть команда (синтаксис могу путать)
C++
1
INC DWORD PTR [EDI]
Вроде "все атомарно", одна команда, и int запишется целиком. Но.. ни одна реализация атомарного инкремента так не делает. Почему?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
21.09.2026, 04:11
Цитата Сообщение от Igor3D Посмотреть сообщение
То есть если пишется напр int, то запишутся все 4 байта, не будет такого что 2 байта старых 2 новых. Важно что адрес должен быть выровнен. Но разве это уже атомарность?
Да, это атомарность инструкций записи и чтения mov. То есть если один поток записывает переменную, а другой читает, то читающий не прочитает наполовину записанную переменную. Читающий прочитает либо полное значение до записи, либо полное значение после записи. Таким же свойством на x86 обладает инструкция xchg. Это указано в спецификации платформы.

Цитата Сообщение от Igor3D Посмотреть сообщение
И с ядрами/когерентностью не уловил
Такую гарантию дает контроллер памяти на x86: то есть даже разные ядра с разными кэшами будут видеть согласованные данные в результате выполнения вышеупомянутых инструкций. На SO есть хорошие посты Peter Cordes на эту тему (https://stackoverflow.com/a/38465341/187690, https://stackoverflow.com/a/36685056/187690)

Цитата Сообщение от Igor3D Посмотреть сообщение
Assembler
1
INC DWORD PTR [EDI]
Вроде "все атомарно", одна команда, и int запишется целиком.
"Одна команда" - это еще ничего не значит. Здесь мало "запишется целиком", здесь нужна атомарность всего инкремента, что является существенно боле громоздкой операцией, чем просто "запишется". Эта "одна команда" не выполняется атомарно.

Например, компилятор Clang транслирует инкременты и декременты volatile переменной в примере из поста #23 именно в inc qword ptr [rax] и dec qword ptr [rax] без префикса lock, то есть именно так, как вы и хотели. Однако в результате в этом примере мы не получаем нуля в финале, ибо эти инструкции "мешали" друг другу, то есть выполнялись неатомарно.

Цитата Сообщение от Igor3D Посмотреть сообщение
Но.. ни одна реализация атомарного инкремента так не делает. Почему?
Как "так"? Без префикса lock? Без lock будет не атомарно. Clang генерирует lock inc qword ptr [rax] для std::atomic<> то есть именно ваш вариант, но с префиксом lock. GCC предпочитает lock add QWORD PTR [rax], 1.
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
21.09.2026, 06:57
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Перечитайте соответствующие сообщения в дискуссии еще раз - и все станет понятно. Специально для вас небольшой дайджест:
1. В сообщении #22 вы говорите, что volatile переменная не будет копироваться в регистр.
2. В сообщении #23 пользователь Алексей1153 в качестве возражения приводит пример кода, в котором volatile переменные загружаются в регистры.
3. В сообщении #24 я выступаю в вашу поддержку: я замечаю пользователю Алексей1153, что данная загрузка в регистр - это не замена/кэширование переменной в регистр, очевидно подразумевавшаяся вами в посте #22, а сиюминутная промежуточная загрузка, необходимая лишь потому, что в системе команд x86 нет команд "память - память" (т.е. команд "пользовательская переменная - пользовательская переменная").
4. Вы соглашаетесь с этим в посте #27
5. При этом в том же посте #27 и далее вы непонятно зачем начинаете разводить посторонний флуд о том, что команды "память - память" в системе команд x86 есть, форся какие-то примеры команд, которые никак не относятся к исходной ситуации из поста #22.
6. И в конечном итоге вы, кажется, вообще потеряли нить и забыли, о чем шла речь, что видно из вашей цитаты выше.
Что это? К чему здесь этот флуд? ¯\_(ツ)_/¯
Флудите здесь вы. Потому как для примера из поста #23 никакие команды память-память совершенно не нужны. Хоть с volatile хоть без. И непонятно зачем вы их сюда приплели.
На кой там сдались какие-то команды память-память? Вы понимаете логику выполнения того кода??? У меня складывается впечатление, что не понимаете.

Добавлено через 4 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Этот пример "работает" потому, что подогнан под аппаратные особенности конкретной платформы: то, что на x86 выровненные команды записи/чтения памяти являются неявно атомарными, то есть не требуют явного префикса lock для атомарности..
Да уж... умеете вы переобуваться в воздухе.
Тогда такая подгонка (вашими словами) возможна на любой архитектуре. Потому как на любой архитектуре есть типы данных с атомарной чтение и записью. Заменить в коде int-ы на эти типы и всё будет работать.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Однако все это не имеет никакого отношения к С++. И, что важно, никаких преимуществ перед штатными средствами организации атомарного доступа не предоставляет, особенно если учесть тонкости оптимизации доступа, описанные мною выше.
Меня просили привести способ синхронизации основанный чисто на volatile. Я привёл.
Также тут некоторыми авторами утверждалось, что volatile невозможно использовать для такой синхронизации. Я привёл пример опровергающий.
Что ещё нет так? Вопрос закрыт? volatile-перменную можно использовать для межпоточной синхронизации? Или сколько ещё будем переливать из пустого в порожнее?

Добавлено через 5 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Да, и вот хороший вопросик. Есть команда (синтаксис могу путать)
C++Скопировано
1
INC DWORD PTR [EDI]
Вроде "все атомарно", одна команда, и int запишется целиком. Но.. ни одна реализация атомарного инкремента так не делает. Почему?
INC [память] - неатомарна с точки зрения многоядерной архитектуры x86. Без префикса lock.
А команды записи и чтения int - атомарны (на той же архитектуре). Хоть с точки зрения одного ядра, хоть с точки зрения многоядерности. И lock им не нужен.

Добавлено через 2 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Таким же свойством на x86 обладает инструкция xchg. Это указано в спецификации платформы.
Разве? Насколько помню - XCHG атомарна только при наличии префикса lock у неё. Без lock - неатомарна в многоядерной системе.
Как именно XCHG (без lock) может быть атомарной, если она выполняет 2 отдельные транзакции по шине: чтение + запись?

Добавлено через 15 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Не уверен что Ваш пример - то что нужно изучать Он ужасно корявый.
Что именно кажется вам там "корявым"?
Цитата Сообщение от Igor3D Посмотреть сообщение
Тестирование может показать наличие багов но не их отсутствие
Т.е. строго доказать что пример верен невозможно
Серьёзно??? Пример простейший - зачем там какое-то "тестироование"? Вроде как достаточно только взглянуть на код. Если конечно язык си знаете....

Добавлено через 1 минуту
Цитата Сообщение от Igor3D Посмотреть сообщение
с точки зрения стандарта правильность Вашего примера не гарантируется. Поток всегда верно прочтет то что записал он сам ("видит" себя) но вот то что писали другие потоки - не гарантируется.
Бред. Чего и в каком месте там "не гарантируется"?
Почитайте хоть какие-то учебники по "атомарности", по архитектурам и операциям в них. Как видно из ваших постов - вы совершенно плаваете в этой теме.
Когда почитаете, разберётесь, тогда и поймёте мой пример.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
21.09.2026, 07:43
Цитата Сообщение от jcxz Посмотреть сообщение
Да уж... умеете вы переобуваться в воздухе.
???

Цитата Сообщение от jcxz Посмотреть сообщение
Тогда такая подгонка (вашими словами) возможна на любой архитектуре. Потому как на любой архитектуре есть типы данных с атомарной чтение и записью. Заменить в коде int-ы на эти типы и всё будет работать.
Чушь полнейшая. Нет таких типов.

На уровне машинного кода атомарность обеспечивается не типом, а операцией. Именно операция должна быть атомарной, а на тип лишь налагаются побочные требования, вроде размера и выранивания. Либо это будет специальная операция, либо это будет специальный модификатор операции (вроде lock на x86).

То, что на x86 внезапно оказалось, что обычные "повседневные" операции mov и xchg даже без lock работают атомарно - это удивительно волшебное уникальное стечение обстоятельств (возможно, являющееся следствием какого-нибудь застарелого костыля в дизайне), которое на других платформах иметь места не будет.

Работоспособность вашего куда с volatile держится случайно-чудесным образом на том, что использованные вами операции натуральным образом странслируются именно в mov. Именно mov чаще всего используется для реализации присваивания на x86 (а ваш код содержит только присванивания). Компилятор при этом не пытался достичь атомарности. Он о ней вообще не думал. Компилятор просто использовал обычный mov, который побочно оказался атомарным. На другой платформе компилятор точно также будет использовать "обычные" повседневные операции при работе с volatile переменной. Которые в общем случае атомарными не будут. Поэтому разглагольствовать на тему того, что что там есть и чего там нет - бесполезно. Компилятор не будет заниматься обеспечивать атомарность - ее и не будет.

И это даже еще не говоря о когерентности памяти в случае наличия нескольких ядер. То, что x86 обеспечивает это "автоматически" - еще одна уникальная удивительная волшебная особенность x86, которой на других платформах не будет.

Цитата Сообщение от jcxz Посмотреть сообщение
Насколько помню - XCHG атомарна только при наличии префикса lock у неё. Без lock - неатомарна в многоядерной системе.
"Помню"? Не смешите меня. По ваши постам видно, что вы буквально на лету занимаете поиском информации в инете. И, разумеется, в найденной вам информации открытым текстом говорилось, что xchg тоже неявно атомарна

https://www.reverseengineering... embly/xchg
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
21.09.2026, 08:03
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Бред сивой кобылы.
На уровне машинного кода атомарность обеспечивается не типом, а операцией.
В чём именно бред? В том что вы не умеете читать написанное?
Попробуйте ещё раз прочитать вами же процитированное:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
типы данных с атомарной чтение и записью.
"чтение" и "запись" - это операции или нет? Если нет, то что это тогда?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
На другой платформе компилятор точно также будет использовать "обычные" повседневные операции при работе с volatile переменной. Которые в общем случае атомарными не будут. Поэтому разглагольствовать на тему того, что что там есть и чего там нет - бесполезно.
Есть какие-то доказательства этого? Приведите их. Примеры в студию компилятора x86, который чтение/запись обычной выровненной переменной типа int сделает не через MOV.
Если не можете привести - то и разглагольствовать нечего.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"Помню"? Не смешите меня. По ваши постам видно, что вы буквально на лету занимаете поиском информации в инете.
По вашим постам:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
на платформе x86 нет подходящих операций формата "память - память" или "непосредственный операнд - память"
видно, что о командах x86 вы узнали только из этой темы. А раньше о них даже не слышали.
Это к тому, кто тут занимается "на лету поиском информации в инете". Чья бы мычала, а ваша бы помолчала.
Гура, с толпами воображаемых "учеников", не знающий даже основ системы команд обсуждаемой архитектуры.


PS: Вобщем - имеющие голову, поймут написанный мной пример с синхронизацией на volatile-переменных. Тролли и пустозвоны - проходите мимо.
Более тут осбуждать нечего. Адьё!
0
21.09.2026, 08:10

Не по теме:

¯\_(ツ)_/¯ Я думаю, что тут все уже безнадежно... Бесполезно тратить время.

0
 Аватар для Recrut_rf
391 / 336 / 66
Регистрация: 14.10.2014
Сообщений: 1,537
21.09.2026, 08:37
Цитата Сообщение от jcxz Посмотреть сообщение
имеющие голову, поймут написанный мной пример с синхронизацией на volatile-переменных.
это вот этот пример ?

Если да, то разве там
C++
1
int volatile state = 0;
как то защищена от модификации другими потоками? То есть всякие мьютексы и атомики не нужны? А что мешает одному потоку прочитать эту переменную, тогда как другой поток успеет пол инта изменить?

P.S. Если что - я не набрасываю, просто хочу разобраться. Во всяких умны книжках по С++, обычно, призывают использовать всякие мьютексы и прочие примитивы синхронизации. Чтоб гонок за данные не было и прочих нежелательных эффектов. А вы своим примером сообщаете, что это нафиг не нужно..... я в ступоре
Сам не сильно в этих стандартах и прочих мануалах для С++ разбираюсь. Наверное, надо идти учить ассемблер
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
21.09.2026, 09:04
Цитата Сообщение от Recrut_rf Посмотреть сообщение
как то защищена от модификации другими потоками? То есть всякие мьютексы и атомики не нужны? А что мешает одному потоку прочитать эту переменную, тогда как другой поток успеет пол инта изменить?
В смысле? Вы код то посмотрите. Там же всего несколько строк. Эта переменная там как раз и нужна чтобы она модифицировалась разными потоками. Что в коде и видно.
Цитата Сообщение от Recrut_rf Посмотреть сообщение
Во всяких умны книжках по С++, обычно, призывают использовать всякие мьютексы и прочие примитивы синхронизации.
Мьютекс - это один из способов. Не единственный. Весьма тяжёлый. Который к тому же может отсутствовать на целевой платформе. Чаще всего можно обойтись более лёгкими способами. Если можно обойтись более лёгкими способами, то их и нужно использовать.
Что и демонстрирует приведённый пример. Который будет нормально работать как под Win, так и например на двухъядерном ARM вообще без какой-либо ОС. Где каждый из "потоков исполнения" - это просто super-loop в main(). Где вы на такой системе найдёте мьютекс?

Под Win иногда пишу. И стараюсь поменьше использовать мьютексы, критические секции и т.п. тяжёлые средства синхронизации. В большинстве случаев стараюсь обойтись либо Interlocked-функциями либо иногда вообще подобно этому - чисто на volatile-переменных. Естественно volatile не отменяет необходимости барьеров и пр. средств. Там где они нужны. Но в том коде они не нужны.
0
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 903
21.09.2026, 12:32
Цитата Сообщение от jcxz Посмотреть сообщение
Мьютекс - это один из способов. Не единственный. Весьма тяжёлый.
Мьютекс в оригинале предоставлялся операционной системой, но потом во многих библиотеках на персоналках был тихо заменён на футекс, который гораздо быстрее. так что не надо его сторониться.
если нет ОС - можете мьютекс сделать на атомиках - нормально работает, просто ресурсы в пустую кушает.

а volatile для процессора это обычная работа с памятью - ибо это только инструкция для компилятора.
если у вас такая простая ситуация что нет гонки данных и всё получается на интерлоках - да пожалуйста пишите как хотите. Но из своего опыта могу сказать что гораздо удобнее один раз написать более высокоуровнемый блок обмена информацией в многопотоке - который допускает гонку и иного потоков и много процессоров и более к вопросу о примитивах синхронизации не возвращаться. Я такой блок даже в однопотоке использую - ибо просто удобно.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
22.09.2026, 08:25
Цитата Сообщение от jcxz Посмотреть сообщение
Что именно кажется вам там "корявым"?
- Неясно зачем нужна такая многопоточность если все задачи (Act1, Act2, Act3, Act4), все равно выполняются последовательно. Хорошо, пусть "это пример", цель выполнить Act1 и Act3 в одном потоке, а Act2 и Act4 в другом. Тогда напрашивается обобщить на разное число потоков и/или задач, а то как-то совсем бедненько, да и копипаста ф-ции не украшает

- Использование локальной переменной "i" непонятно. Может "так заработало, не трогай и не дыши!"? Угадал?

- Реализация Sleep имеет фиксированное/константное время задержки. Это источник забот, и так Вы признаете что ни на какую оптимальность не претендуете, абы работало.

- нет кода завершения/отмены, иногда требуется и suspend/resume, ну то ладно, это пример

Как надо было делать. В многопоточности есть схемы/табии что подходят для массы задач, в том числе и для Вашего примера. Напр в справочнике посмотрите std::condition_variable::notify_all, переделать тамошний примерчик несложно. По сути он переписывается тысячекратно, схема одна и та же. Возможно Вы скажете или подумаете
Там же до фига всего (condition_variable, мутекс, лок и др). А я (крутой мужик) вот одним гвоздем volatile все сделал! И все работает! А эти тупари не могут и не хотят понять мой код!
Ничего, "это пройдет" Придет понимание что если уж велик - то лучше/быстрее типового решения, придет умение подсчитывать во что этот велик обойдется и.т.д. Хотя, судя по Вашему поведению, это будет не скоро
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.09.2026, 08:25

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...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
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. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru