
c++中的内存对齐是什么?
内存对齐是什么?
从理论上讲,计算机可以从任何位置访问任何变量,但是实际上,系统对这些变量的存储地址有限制。 通常,将变量的第一个地址设置为特定数字N的倍数,即内存对齐。
为什么要内存对齐?
理论上计算机对于任何变量的访问都可以从任意位置开始,然而实际上系统会对这些变量的存放地址有限制,通常将变量首地址设为某个数N的倍数,这就是内存对齐。
硬件平台限制,内存以字节为单位,不同硬件平台不一定支持任何内存地址的存取,一般可能以双字节、4字节等为单位存取内存,为了保证处理器正确存取数据,需要进行内存对齐。
提高CPU内存访问速度,一般处理器的内存存取粒度都是N的整数倍,假如访问N大小的数据,没有进行内存对齐,有可能就需要两次访问才可以读取出数据,而进行内存对齐可以一次性把数据全部读取出来,提高效率。
内存对齐规则
数据成员对齐规则:struct或者union的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员都按照#pragma pack数值和这个数据成员自身大小中更小的那个进行对齐。
整体对齐规则:struct或者union的首地址按照内部最大数据成员的大小和#pragma pack数值较小的那个N进行对齐,并且结构体的总大小为N的整数倍,如有必要编译器也会在最后一个成员后面填充一些字节用于对齐。
如何进行内存对齐?
std::aligned_storage
std::aligned_storage用于创建一块对齐的内存,具体实现如下
使用方式上面已经介绍过了,Align大小也可以不填,默认会是采用最大最有益的对齐大小,大家可能源码里有些语句不了解含义,如下:
__attribute((packed))告诉编译器取消编译中的内存对齐优化,采用实际占用的字节数进行对齐。
__attribute((aligned(N))) 告诉编译器在编译过程中按照N字节对齐,经过测试这个N只有大于结构体中最大的变量的大小才有用。
__attribute__((aligned)) 后面不接数字,告诉编译器根据目标机制采用最大最有益的方式对齐,基本上就是16字节对齐。
alignof(X) 返回某类型的对齐大小,与std::alignment_of类似,这两个功能完全相同,但是std::alignment_of可以用于模板元编程。
类大小的测试
普通类型代码如下:
具体的计算方式在代码中已经添加注释。
带有虚函数的类的大小测试:
通过结果可知,一个类带有虚函数,类的大小会多8个字节,这8个字节是虚函数表指针的大小,指针类型为长整型long,在32位机器上是4字节,64位机器上是8字节。
如有任何问题,欢迎与我交流~
