170 похожих чатов

Почему-То встречается мнение, что атомики не дают никаких гарантий, что

чтения не будут отставать от реальных значений. мол, для 100% уверенности не только в разделении доступа, но и консистентности, нужно использовать мьютексы. однако я не могу нигде найти разъяснений, почему так. кеш процов может невовремя обновиться?

25 ответов

33 просмотра

это странное мнение

Наверное, потому что это так: чтение памяти через атомик не даёт гарантии актуальности значения :)

Vadim-Inshakov Автор вопроса
Daniel Podolsky
это странное мнение

https://groups.google.com/g/golang-nuts/c/0uPDCRiBWqc/m/JISqbkl7288J

Vadim-Inshakov Автор вопроса
Roman Timofeev
Наверное, потому что это так: чтение памяти через ...

то есть записать в одну процессорную инструкцию мы можем атомарно, а для чтения придется подождать загрузки в кеш? но ведь мы туда уже положили значение при записи, почему нет гарантий не понимаю 🤷‍♂️ что значение может быть вытеснено из кеша и придется все-таки идти в память, а там stale значение?

Vadim-Inshakov Автор вопроса
Vadim Inshakov
суть атомиков же

Количество инструкций зависит от архитектуры.

Vadim Inshakov
например?

https://github.com/golang/go/blob/master/src/runtime/internal/atomic/asm_amd64.s#L84

Vadim Inshakov
https://groups.google.com/g/golang-nuts/c/0uPDCRiB...

атомик дает всего две гарантии 1. значение обновится целиком 2. компилятор не переставит инструкции так, чтобы те чтения, что в тексте программы после записи, оказались перед на amd64 мы еще знаем, что atomic приведет к синхронизации кешей процессоров, и это будет тормозить больше ничего атомик нам не дает.

Vadim Inshakov
то есть записать в одну процессорную инструкцию мы...

А где гарантии, что сразу после записи кто-то не записал туда же с другого cpu и вы прочитаете совершенно другое значение? :)

Vadim-Inshakov Автор вопроса
Roman Timofeev
и всё это только в рамках 1 ядра.

но ведь общий кеш гарантирует, что все ядра прочитают одно и то же, актуальное для всех, значение. иначе бы это не работало: https://play.golang.org/p/cOTzCb1rroy

Vadim-Inshakov Автор вопроса
Daniel Podolsky
атомик дает всего две гарантии 1. значение обнови...

то есть есть архитектуры, где это https://play.golang.org/p/cOTzCb1rroy даст некорректный результат, потому что разные ядра будут видеть разное значение в кеше?

Roman Timofeev
и всё это только в рамках 1 ядра.

какого такого 1 ядра. для 1 ядра и атомики ненужны, всё и так почти хорошо было до появления HT и двухядерников

Vadim Inshakov
но ведь общий кеш гарантирует, что все ядра прочит...

Добавьте какую-то логику, завязанную на значение счётчика и сразу поймёте в чём проблема. Например, при ops == 50 вы делаете декремент до 0, потом снова инкремент до верхнего порога.

Vadim Inshakov
но ведь общий кеш гарантирует, что все ядра прочит...

общего кэша нет для NUMA серверов (н.р. на 2x Xeon-ах). В этом случае синхронизация кэша с атомиками будет через межпроцессорную QPI шину. А также нет когерентности кешей L1,L2,L3 между ядрами на одном процессоре.

Max Antonov
какого такого 1 ядра. для 1 ядра и атомики ненужны...

двухпроцессорные конфигурации были уже в 90х.

Roman Timofeev
двухпроцессорные конфигурации были уже в 90х.

не ну так то да, как и атомарные операции для них ) просто более массово это пошло с появлениям ht, потом двух и x-ядерников. И соответсвенно вся тема с lockfree алгоритмами

Max Antonov
какого такого 1 ядра. для 1 ядра и атомики ненужны...

Кстати, для 1 ядра тоже важны, правда не в прикладном коде

Max Antonov
не ну так то да, как и атомарные операции для них ...

По идее, ht тут не должен быть при делах, кеши общие же

Vadim-Inshakov Автор вопроса
Roman Timofeev
Добавьте какую-то логику, завязанную на значение с...

абсолютно предсказуемые результаты: https://play.golang.org/p/gv3YP7ufQFA в чем загвоздка? что должно пойти не так?

Roman Timofeev
По идее, ht тут не должен быть при делах, кеши общ...

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

Vadim Inshakov
абсолютно предсказуемые результаты: https://play.g...

Вы сделали не то. Я говорил о том, чтобы значение ops "гуляло" в интервале от 0 до 50, а вся эта толпа горутин работали как единый механизм, продвигающий значение ops от 0 до 50 и обратно.

сложность реализации чего-либо, н.р. счетчики, простые флаги, атомарные значения сами по себе - более менее просты, а вот мапу или дерево на атомиках - на это уже есть и научные работы (с обоснованием отсутсвия гонок). Само представление о сложности таких алгоритмов можете посмотреть в статьях по lockfree. На том же хабре есть например.

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта