Комментарии 11
эта программа у меня стабильно падает где-то за 7-10млн итераций чтения
У меня она стабильно сразу выдаёт
Bus error (core dumped)
Ваша x86 архитектура позволяет слишком много вольностей )
PS -fsanitize=undefined явно детектит проблему и в gcc и в clang.
а в режиме бин трансляции если таргет платформа была x86 что будет?
емнип, ошибку при невыровненном чтении на x86 тоже можно получить, если в какую-нибудь avx инструкцию, требующую выравнивание, подать невыровненный адрес
А так, да - дебажить bus-error проще чем что-то стреляющее с такой малой вероятностью (и космические лучи обвинишь, ища разгадку или репродьюс)
а в режиме бин трансляции
Тут уже от транслятора зависит, сконвертирует он один атомик в другой или навернёт логику с локами. Под рукой ничего нет чтобы быстро проверить.
Да, SIMD на x86 часто требует выравнивания (хотя есть, скажем, movups).
дебажить bus-error проще
Согласен. Но санитайзер тоже порадовал, надо бы почаще использовать...
хм, напоминает старый анекдот про японскую бензопилу и суровых лесорубов
Есть бит RFLAGS.AC, который вызывает исключение #AC при невыравненном доступе. Им пользоваться невозможно, потому что почти все компиляторы (не только C) генерируют код, нарушающий это правило.
В сравнительно новых интеловских процессорах появился MSR_MEMORY_CTRL.SPLIT_LOCK_DISABLE, разрешение которого приводит к #AC при невыравненных locked доступах.
В вашем примере это бы сработало из-за иначе ненужного seq-cst режима. Если бы использовался relaxed или acq/rel, то на x86 они обычно моделируются простыми load и store, и split lock detection бы не сработал.
P.S. Явление называется 'torn writes' и в дикой природе встречается начиная с Core2 (~2008 г).
а malloc <...> этого не делают
Делает. Он возвращает всегда максимально выровненный указатель.
Спасибо за уточнение. Добавил апдейт в текст
"Максимально" это конечно перегиб, всё же malloc гарантированно выровнен по выравниванию наиболее выровненного встроенного сишного типа (обычно выровнен в два машинных слова), чего просто атомикам, конечно, и хватит, но всё же для гарантий в более общем случае лучше использовать aligned_alloc, например при выравнивании по ширине кеш-линии, как иногда делается

Обманываем atomic