英文:
Attribute to enforce padding after a variable?
问题
There is no direct attribute to enforce padding after a variable in C/C++. You can achieve this by adding a padding variable after foo
or by aligning the following variable using __attribute__((aligned(CACHE_LINE_SIZE)))
.
英文:
Is there an attribute to enforce padding after a variable?
I have a volatile (non-cached) variable declared as such:
volatile int foo __attribute__((aligned(CACHE_LINE_SIZE));
I would like to prevent other variables from being allocated to the same cache line, to avoid coherency issues.
I can add a padding variable after foo, or set the __attribute__((aligned(CACHE_LINE_SIZE))
to the following variable in the same compilation unit. However I was wondering whether there is a cleaner way to do this, such as adding an attribute to variable foo
itself to enforce padding.
答案1
得分: 4
在这篇博文中介绍了一些选项:[将数据与缓存行对齐](https://subscription.packtpub.com/book/iot-&-hardware/9781838821043/3/ch03lvl1sec27/aligning-data-with-cache-lines)。
我建议使用 C++11 的 [alignas](https://en.cppreference.com/w/cpp/language/alignas):
最简单的版本
```cpp
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; // 这里不需要指定长度。这一行可以完全省略
// 自动填充以使 sizeof(my_padded_type) == CACHE_LINE_SIZE
};
my_padding_type foo;
std::cout<< sizeof(my_padding_type) <<"\n"; // 等于 CACHE_LINE_SIZE
填充会被编译器自动完成,可以参考这里的示例 here。
<details>
<summary>英文:</summary>
Some options are introduced in this blog article: [Aligning data with cache lines](https://subscription.packtpub.com/book/iot-&-hardware/9781838821043/3/ch03lvl1sec27/aligning-data-with-cache-lines).
I would suggest to use the C++11 [alignas](https://en.cppreference.com/w/cpp/language/alignas):
The simplest version
```cpp
using my_padded_type = struct alignas(CACHE_LINE_SIZE) { int value;} ;
Padding bits are added automatically.
You can verify it by checking sizeof(my_padded_type)
. See details below.
Other options:
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
or
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
The padding is done automatically by the compiler, see the example here.
答案2
得分: 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 和 Bar 在不同的缓存行上
};
alignas(std::hardware_destructive_interference_size)
struct Foo // Foo 被保证在自己的缓存行上
{
};
英文:
This is what std::hardware_destructive_interference_size
was added for:
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
{
};
答案3
得分: 3
alignas(CACHE_LINE_SIZE)
on every variable should do the trick:
struct X {
alignas(CACHE_LINE_SIZE) int foo;
alignas(CACHE_LINE_SIZE) int bar;
};
I assume you are asking about aligning struct members.
If you don't care about the alignment of subsequent members but want to make sure that no other data is placed on foo
's cache line, manually fill it with padding bytes:
struct X {
alignas(CACHE_LINE_SIZE) int foo;
char paddingbytes[CACHE_LINE_SIZE - sizeof(int)];
// Other data members
};
英文:
alignas(CACHE_LINE_SIZE)
on every variable should to the trick:
struct X {
alignas(CACHE_LINE_SIZE) int foo;
alignas(CACHE_LINE_SIZE) int bar;
};
I assume you are asking about aligning struct members.
If you don't care about the alignment of subsequent members, but want to make sure that no other data is placed on foo
's cache line, manually fill it with padding bytes:
struct X {
alignas(CACHE_LINE_SIZE) int foo;
char paddingbytes[CACHE_LINE_SIZE - sizeof(int)];
// Other data members
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论