内存结构体对齐总结

本文探讨了结构体对齐的目的及其对访问速度的影响,并详细介绍了如何通过调整结构体成员变量的排列顺序来优化缓存行使用,从而提高程序运行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构体对齐目的:

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



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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值