c++ - 可以使用 gcc 中的多个对齐属性来保证缓存行分离吗?

标签 c++ c caching gcc

我试图准确理解 gcc 中的 aligned 属性是如何工作的,以及它如何用于创建缓存行对齐的数据结构。我有一个包含 2 个成员的结构,我希望在缓存行为 64 字节的不同缓存行上使用它。我认为以下内容不够,因为它只能保证单个成员的对齐:

struct alignTo64ByteCacheLine_BAD {
   int _onCacheLine1
   int _onCacheLine2 __attribute__((aligned(64)))
}

然而,以下两个结构是否保证将它们的成员放在不同的缓存行中?此外,结构本身的 aligned(64) 属性是否会将结构填充为 64 字节的倍数以用于数组,还是必须手动完成?

struct alignTo64ByteCacheLine1 {
   int _onCacheLine1
   int _onCacheLine2 __attribute__((aligned(64)))
} __attribute__((aligned(64)))

struct alignTo64ByteCacheLine2 {
   int _onCacheLine1 __attribute__((aligned(64)))
   int _onCacheLine2 __attribute__((aligned(64)))
} 

最佳答案

I have a struct with 2 members, which I want on different cache lines where a cache line is 64 Bytes. I assume the following is not good enough because it will only guarantee the alignment of a single member:

struct alignTo64ByteCacheLine_BAD {
   int _onCacheLine1
   int _onCacheLine2 __attribute__((aligned(64)))
}

你错了:上面的代码将导致两个成员在 64 位地址上对齐。这是根据以下事实得出的结论

  • 结构的对齐要求必须是每个成员的对齐要求的倍数(否则不能保证至少有一个成员的对齐),并且

  • 第一个成员之前不能有填充。

因此,对于只有两个成员的结构,为第二个成员指定对齐方式可确保第一个成员至少具有同样严格的对齐方式。因此,此替代方案与您的其他两个替代方案具有相同的实际效果。

此外,这确保每个成员都位于其缓存行的开头,这比您表达的要求更严格。如果您确实只需要成员位于不同的缓存行上,那么只对齐第二个就足够了,因为第一个成员必须在内存中排在第二个之前。

但是,另请注意,这似乎效率极低。对齐要求将要求编译器将此结构填充到(至少)128 字节的总大小,其中仅使用了 8 个(因为我们谈论的是 GCC,我们知道我们有 4 字节 ints)。每个成员将是其缓存行中的唯一内容。您没有说为什么要这样做,但它似乎很可能会严重影响您的缓存命中率。

Also, will the aligned(64) attribute on the struct itself pad the struct out to a multiple of 64-bytes for use in arrays, or does that have to be done manually?

结构大小将被填充到其对齐要求的倍数,这样类型的数组就不会强制任何元素不对齐。

关于c++ - 可以使用 gcc 中的多个对齐属性来保证缓存行分离吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51216314/

相关文章:

caching - Varnish :禁止使用任何GET参数的URL

java - 同步缓存的最佳方法

c++ - 如何在 cpp 中使用 std::regex_replace() 函数查找和替换

c++ - new/delete 和 malloc/free 有什么区别?

C 编程 : Using fscanf(), fopen() 和格式字符串问题

c++ - 在指向 T 的指针、T 的数组和指向 T 的数组的指针之间进行转换是否有未定义的行为?

c++数据库连接到mysql

c++ - 在不复制的情况下从 Eigen::SparseMatrix 中提取 block /ROI

c - 它是 C 语言中的通用堆栈数据结构链表实现吗?

java - 如何更换 ignite 缓存?