内存结构体对齐总结

来源:互联网 发布:思迅软件破解版 编辑:程序博客网 时间:2024/04/27 14:26

结构体对齐目的:

1:访问速度:为了不让同一个变量(同时包括整个结构变量和结构体内部成员变量)分布在多个cache line上,然后两次访问内存。

2:平台限制:有些平台不能随意读取某个偏移的地址变量

如结构体:

struct AT
{
    char a;
    char b;
    int  c;
    char d;
};


因为cpu是以cacheline为单位读写内存的。如x86_64的cacheline的大小为8个字节共64位,利用这一特性我们能做什么优化呢?


1:结构体起始地址尽量是cacheline的整数倍。

2:结构体变量尽量是cacheline的整数倍。

3:结构体成员变量尽量是在同一个cacheline中。(特别是要访问连续的几个成员变量情况,可以一次性读入)


当然下面这种情况需要认为代码中避免的:如果两个成员变量被不同的core频繁修改的话(cache一致性维护代价非常高),那最好不要将这两个变量落到同一个cache line中。


从上面得出一个宗旨:同一个成员变量不要跨cache line:


具体做法:找到一个最小单位n,它取决于下面的最小值:

1:人为指定:#pragma pack指定的数值

2:cache line大小

3:结构体内部最大的基本数据类型成员


当确定好n时,之后的对齐规则是:

1:结构体变量起始地址为n的整数倍

2:结构体成员变量的地址规则:取min(自身大小,n大小)

a:当自身大小大于等于n时,那么地址为n的整数倍:如

#pragma pack(4)struct s7{char a;double d;};#pragma pack()double为8,cacheline为8,指定为4;那么n为4;sizeof(s7)为12

b:当自身大小小于n时:那么为自身大小的的整数倍:如:

struct s5{char a;char b;int  c;double d;};doube为8,cacheline为8,没有指定,那么n为8,sizeof(s5)为16


3:总长度为n的总数倍,如:

struct s6{char a;char b;double d;int  c;};double为8,cacheline为8,那么n为8,sizeof(s6)为24



写代码的时候有一个宗旨:按所占字节大小从小到大排序。


0 0
原创粉丝点击