如何在变量后强制执行填充属性?

10

有没有一种属性可以强制在变量后面添加填充?

我声明了一个易失性(非缓存)变量,如下所示:

volatile int foo __attribute__((aligned(CACHE_LINE_SIZE));

我想要防止其他变量被分配到同一缓存行,以避免一致性问题。 我可以在foo后面添加填充变量,或者在同一编译单元中将__attribute__((aligned(CACHE_LINE_SIZE))设置为下一个变量。但是我想知道是否有更简洁的方法来实现这一点,例如向变量foo本身添加属性以强制填充。


2
类似于struct { int foo; char padding[CACHE_LINE_SIZE - sizeof(int)]; }的东西? - KamilCuk
std::aligned_storage 是否符合你的需求? - Richard Critten
2
@KamilCuk 根据您的定义,不能保证一个对象只映射到一个缓存行。 - Daniel Langr
union { int foo; char size[CACHE_LINE_SIZE]; } 看起来更好。 - KamilCuk
即使它确实存在,std::aligned_storage在C++23中已被弃用。 - Fulgen
3个回答

4

这就是为什么添加了std::hardware_destructive_interference_size:

struct X
{
    alignas(std::hardware_destructive_interference_size) int Foo;
    alignas(std::hardware_destructive_interference_size) int Bar; // Foo and Bar are on different cache lines
};

alignas(std::hardware_destructive_interference_size)
struct Foo // Foo is guaranteed to be on its own cache line
{
};

你能找到关于 alignas(64) struct Foo {} 行为的参考文献或标准文档吗?我已经在 GCC/Clang 中进行了测试。这两个编译器确保 Foo 在其自己的高速缓存行上。但是我在 C++ 标准中找不到任何保证。 - gdlmx

4
这篇博客文章介绍了一些选项:将数据与缓存行对齐
我建议使用C++11 alignas
最简单的版本。
using my_padded_type = struct alignas(CACHE_LINE_SIZE) { int value;} ;

填充位会自动添加。

您可以通过检查 sizeof(my_padded_type) 来验证它。详见下文。

其他选项:

alignas(CACHE_LINE_SIZE) int foo1, foo2;
alignas(CACHE_LINE_SIZE) union { int value; char size[CACHE_LINE_SIZE]; } foo;

std::cout  << "&foo1: " << &foo1 << '\t'
           << "&foo2: " << &foo2 << '\n';
// &foo1: 0x7ffd833ebe00 &foo2: 0x7ffd833ebe40

或者

struct alignas(CACHE_LINE_SIZE) my_padded_type {
    int foo;  //  size: 4 
    char p;   //  do not need to specify length here. this line can be omitted entirely
    // auto padding so that sizeof(my_padded_type) == CACHE_LINE_SIZE
}; 
my_padding_type foo;
std::cout<< sizeof(my_padding_type) <<"\n"; // equals CACHE_LINE_SIZE

编译器会自动完成填充,可以参考这里的示例。


3

在每个变量上使用alignas(CACHE_LINE_SIZE)应该就可以解决问题:

struct X {
    alignas(CACHE_LINE_SIZE) int foo;
    alignas(CACHE_LINE_SIZE) int bar;
};

演示现场

我认为你在问有关结构成员对齐的问题。

如果您不关心后续成员的对齐,但希望确保没有其他数据放置在foo的缓存行上,请手动填充它以进行填充字节:

struct X {
    alignas(CACHE_LINE_SIZE) int foo;
    char paddingbytes[CACHE_LINE_SIZE - sizeof(int)];
    // Other data members
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接