简体   繁体   English

为 struct 成员分配的内存是否连续? 如果结构成员是数组怎么办?

[英]Is the memory allocated for struct members continguous? What if a struct member is an array?

In C/C++ suppose I define a simple struct named test as follows.在 C/C++ 中,假设我定义了一个名为test的简单结构,如下所示。

struct test
{
   double height;
   int    age;
   char   gender;
}

For a specific instance of this struct say test A are A.height, A.age, A.gender contiguous in memory?对于此结构的特定实例,说test A在内存中是连续的A.height, A.age, A.gender

More generally, how do the layouts in memory for a Structure of Arrays and an Array of structures look like?更一般地说,数组结构和结构数组在内存中的布局如何? A picture would be really helpful.一张照片真的很有帮助。

They will not necessarily be contiguous in memory.它们在内存中不一定是连续的。 This is due to struct padding .这是由于struct padding

However, in your particular case, it may very well be contiguous.但是,在您的特定情况下,它很可能是连续的。 But if you changed the order to something like this:但是,如果您将顺序更改为如下所示:

struct test
{
    char   gender;
    int    age;
    double height;
}

then they most likely will not be.那么他们很可能不会。 However, in your particular case, you will still likely get padding after gender , to realign the struct to 8 bytes.但是,在您的特定情况下,您仍然可能会在gender之后填充,以将结构重新对齐为 8 个字节。


The difference between SoA ( Struct of Arrays ) and AoS ( Array of Structs ) would be like this: (SOA阵列的结构)和AOS(结构的数组)之间的差将是这样的:

SoA:索A:

-----------------------------------------------------------------------------------
| double | double | double | *pad* | int | int | int | *pad* | char | char | char |
-----------------------------------------------------------------------------------

AoS:服务范围:

-----------------------------------------------------------------------------------
| double | int | char | *pad* | double | int | char | *pad* | double | int | char |
-----------------------------------------------------------------------------------

Note that AoS pads within each struct.请注意,AoS 填充在每个结构中。 While SoA pads between the arrays.而 SoA 在阵列之间填充。

These have the following trade-offs:这些有以下权衡:

  1. AoS tends to be more readable to the programmer as each "object" is kept together.由于每个“对象”都保存在一起,因此AoS对程序员来说更具可读性。
  2. AoS may have better cache locality if all the members of the struct are accessed together.如果结构体的所有成员一起访问, AoS可能具有更好的缓存位置。
  3. SoA could potentially be more efficient since grouping same datatypes together sometimes exposes vectorization. SoA可能会更有效,因为将相同的数据类型组合在一起有时会暴露矢量化。
  4. In many cases SoA uses less memory because padding is only between arrays rather than between every struct.在许多情况下, SoA使用较少的内存,因为填充仅在数组之间而不是在每个结构之间。

The individual fields are contiguous in the sense that there will be no other variables stored in-between them.各个字段是连续的,因为它们之间不会存储其他变量。 They are also guaranteed to be stored in the order that you declared.它们也保证按照您声明的顺序存储。 But the compiler is free to insert padding in-between the individual fields to align things to word boundaries, for instance.但是,例如,编译器可以自由地在各个字段之间插入填充以将事物与字边界对齐。 So the following:所以如下:

struct test
{
    double height;
    char   gender;
    int    age;
};

may look like this in memory:在内存中可能看起来像这样:

         +7  +6  +5  +4  +3  +2  +1  +0
        +---+---+---+---+---+---+---+---+
0x0000  |            height             |
        +---+---+---+---+---+---+---+---+
0x0008  |      age      |           |gen|
        +---+---+---+---+---+---+---+---+

As for the difference between SoA and AoS, they're laid out exactly as you might imagine.至于 SoA 和 AoS 之间的区别,它们的布局与您想象的完全一样。

Other than the standard disclaimer of "it depends on your platform, compiler, blahblahblah"... yes, height , age , and gender will be contiguous in memory with no padding in between:除了“这取决于您的平台、编译器、blahblahblah”的标准免责声明之外……是的, heightagegender在内存中将是连续的,中间没有填充:

height|age|gender

However, if you have an array of test , each array element will have padding in between them after each's gender so that the next element's height is properly aligned.但是,如果您有一个test数组,则每个数组元素在每个gender之后都会在它们之间填充填充,以便下一个元素的height正确对齐。

|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...

If your goal is to use the least amount of memory possible, then you should go with "structure of arrays" since it uses no padding.如果您的目标是尽可能使用最少的内存,那么您应该使用“数组结构”,因为它不使用填充。

|height0|height1|...

|age0|age1|...

|gender0|gender1|...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM