Pull to refresh

Comments 23

То есть разработчик не использовал атомики в многопоточном коде а теперь страдает?

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

Гораздо быстрее такие баги возникнут в программах, изначально написанных с дефектами.
Не увидел в приведённых примерах какой-либо работы с моделью памяти с++ вообще.
C++ 11 уже довольно зрелый. Можно пользоваться.
О том, как это делать, можно прочитать тут: habr.com/ru/post/517918

К сожалению, под ARM нет такой инструкции

ISB/DSB/DMB - не оно?

Они немного про другое. Барьер гарантирует что операции работы с памятью доедут, но штук типа LOCK INC нету.

А эксклюзивная загрузка или сохранение разве не из этой серии?

LDAXR? ога есть, только на V8a.

Помню, что LDEX и STEX я пользовался еще в 2013 году и это была версия v6.

LDREX/STREX начиная с ARM6
LDARX  это чего-то древнючее, едва-ли не PowerPCшное.

Не не, LDARX действительно новое, что-то вроде DSB+LDREX одной инструкцией, если правильно понял описание.

Так там (пардон, нужно было подлиннее цитату сделать) речь как раз об отсутствии аналога MFENCE шла.

но штук типа LOCK INC нету.

Ваши данные давно устарели
В ARMv8.1 (2014г) есть СAS, атомарный инкремент в одну инструкцию и много других атомарных операций.

developer.arm.com/documentation/100076/0100/a64-instruction-set-reference/a64-data-transfer-instructions/casa--casal--cas--casl--casal--cas--casl

developer.arm.com/documentation/100076/0100/a64-instruction-set-reference/a64-data-transfer-instructions/ldadda--ldaddal--ldadd--ldaddl--ldaddal--ldadd--ldaddl

Грубо говоря, одно ядро CPU изменяет значение счётчика, записывает его в свой кэш, но принимает решение передать его в память попозже, а в это время значение счётчика изменяет другое ядро CPU.

Получается, что в вашей системе нет поддержки аппаратной когерентности кэшей?

Там есть некий store buffer, куда значение попадает до записи в кеш.

буфер записи это частое решение в процессорах.При проверке аппаратной когерентности кэшей он гарантированно должен проверяться.

Хотя, возможно Вы и правы. Буфер записи перед кэшем это просто еще запись которая не добралась до кэша. При проверке когерентности кэшей буфер записи может и не проверяться.

Про "большие армы" не скажу, но на CortexM вроде можно ценой некоторой недетерминированности сделать CAS.

BREAKING NEWS: Неправильный код может работать неправильно!

Спасибо за ссылку. Значит еще с версии 6 у них все это есть.

А ещё у ARM'ов бывают разные ядра внутри одного процессора (разная частота, например). Из-за этого бывают тонкости при переключении контекста.

Как и у х86 теперь.

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

add rcx, [rbx] ; rcx += *rbx

Это сильно неправильный ARM, не удивительно, что он делает неправильный результат.

Sign up to leave a comment.