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

huangapple go评论79阅读模式
英文:

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-&amp;-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  &lt;&lt; &quot;&amp;foo1: &quot; &lt;&lt; &amp;foo1 &lt;&lt; &#39;\t&#39;
           &lt;&lt; &quot;&amp;foo2: &quot; &lt;&lt; &amp;foo2 &lt;&lt; &#39;\n&#39;;
// &amp;foo1: 0x7ffd833ebe00 &amp;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&lt;&lt; sizeof(my_padding_type) &lt;&lt;&quot;\n&quot;; // 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
};

Live demo

英文:

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;
};

Live demo

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
};

huangapple
  • 本文由 发表于 2023年5月22日 16:26:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76304300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定