Проведя некоторое исследование алгоритмов блокировки/ожидания, я наткнулся на проблему ложного обмена. Копание немного больше привело меня к исходному коду Фолли (библиотека Facebook С++) и более конкретно к этому файлу заголовка и определению макроса FOLLY_ALIGN_TO_AVOID_FALSE_SHARING
(в настоящее время в строке 130). Что меня больше всего удивило на первый взгляд: значение 128 (т.е.: вместо 64)...
/// An attribute that will cause a variable or field to be aligned so that
/// it doesn't have false sharing with anything at a smaller memory address.
#define FOLLY_ALIGN_TO_AVOID_FALSE_SHARING __attribute__((__aligned__(128)))
AFAIK, блоки кэша на современных процессорах имеют длину 64 байта и фактически, все ресурсы, которые я нашел до сих пор по этому вопросу, включая эту статью от Intel, говорят о 64 байты, выравнивающие и, чтобы помочь работать с ложным совместным использованием.
Тем не менее, люди в Facebook выравнивают и заполняют их члены класса до 128 байтов, когда это необходимо. Затем я узнал начало объяснения чуть выше FOLLY_ALIGN_TO_AVOID_FALSE_SHARING
:
enum {
/// Memory locations on the same cache line are subject to false
/// sharing, which is very bad for performance. Microbenchmarks
/// indicate that pairs of cache lines also see interference under
/// heavy use of atomic operations (observed for atomic increment on
/// Sandy Bridge). See FOLLY_ALIGN_TO_AVOID_FALSE_SHARING
kFalseSharingRange = 128
};
Пока он дает мне немного больше деталей, я все еще чувствую, что мне нужны некоторые идеи. Мне интересно, как синхронизация смежных строк кэша или любая работа RMW на них могут мешать друг другу при интенсивном использовании атомных операций. Может кто-нибудь, пожалуйста, просветит меня о том, как это может произойти?