在做一些关于无锁/无等待算法的研究时,我偶然发现了错误共享问题。再深入一点,我找到了 Folly 的源代码(Facebook 的 C++ 库),更具体地说,是这个头文件和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,现代 CPU 上的缓存块长度为 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 操作如何相互干扰。 有人可以告诉我这怎么可能发生?