Делюсь бесполезными знаниями.
На x86 код
counter.fetch_add(1, std::memory_order_relaxed);
И
counter.fetch_add(1);
Выполняются одинакого быстро. Это бесполезное знание.
Полезное знание тут заключается в том, что, оказывается, бенчмарки можно запускать в godbolt. (Бенчмарк не мой, подглядел в другом месте). (А ещё на самом деле в более сложной функции relaxed допускает переупорядочивание недоступное при seq но это вообще сложные материи и не сумел сконструировать пример, который бы это воспроизводил).
Да, аппаратная инструкция может задавать более серьезное упорядочивание, чем требует модель памяти. Тут должны быть ссылки на реальные документы и доказательства, но хей, мы тут деградацией занимаемся, а не образованием.
Ну вот теперь мы это знаем. Что же это нам дает? Да ничего не дает.
Если мы походим по популярным проектам, то увидим, что везде fetch_add используется с relaxed.
PyTorch
Folly
LevelDB
Boost
gRPC
Скорее всего потому, что библиотеки популярные, и используются на разных архитектурах.
Но пусть я делаю что-то только для x86. Допустим я разобрался, и умею читать всякое такое (а я не умею, я - деградарий):
define void
@inc1(ptr nocapture %p) nounwind ssp {
; CHECK-LABEL: inc1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lock incl (%rdi)
; CHECK-NEXT: retq
;
; SLOW_INC-LABEL: inc1:
; SLOW_INC: # %bb.0: # %entry
; SLOW_INC-NEXT: lock addl $1, (%rdi)
; SLOW_INC-NEXT: retq
entry:
%0 = atomicrmw add ptr %p, i32 1 monotonic
ret void
}
Есть ли у меня мотивация писать
counter.fetch_add(1);
???
Никакой мотивации. Я напишу relaxed просто на всякий случай. А мало ли что.
Получается, что знание, что в данном случае оно не нужно - просто бесполезное. Ну не узнал я что-то, и фиг бы с ним. Зачем я потратил на это столько времени? Для чего, мистер Андерсен?
И как бы мне получать полезные знания, не тратя время на бесполезные?
А тут ещё эти ваши нейронки, дискредетирующие знания в голове вцелом... Нипанятна...