c++ 属性是否在变量后强制填充?

nhhxz33t  于 2023-05-24  发布在  其他
关注(0)|答案(3)|浏览(166)

是否有一个属性来强制填充变量后?
我有一个volatile(非缓存)变量声明如下:

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

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

1sbrub3j

1sbrub3j1#

在这篇博客文章中介绍了一些选项:Aligning data with cache lines
我建议使用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

填充是由编译器自动完成的,请参阅此处的示例。

vktxenjb

vktxenjb2#

以下是添加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
{
};
mklgxw1f

mklgxw1f3#

alignas(CACHE_LINE_SIZE)在每个变量上都应该是这样的:

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

Live demo
我假设你是在问关于对齐结构体成员的问题。
如果你不关心后续成员的对齐方式,但想确保没有其他数据放在foo的缓存行上,可以手动填充填充字节:

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

相关问题