转载自: https://blog.csdn.net/qq_32916805/article/details/117637192
内存对齐
为了方便CPU用指令对内存进行访问,通常要求某种类型对象的地址必须是某个值K(通常是2、4或8)的倍数,如果一个变量的内存地址正好位于它长度的整数倍,我们就称他是自然对齐的。不同长度的内存访问会用到不同的汇编指令,这种对齐限制简化了形成处理器和存储器系统之间接口的硬件设计,提高了内存的访问效率。
通常对于各种类型的对齐规则如下:
数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每个数据类型都要对齐
对于SIMD的内存对齐是指__m128等union在内存中存储时的存储方式。然而由于结构内存对齐的规则略微复杂,我们以结构为例进行说明:
一般情况下,由于内存对齐的原因存储多种类型数据的结构体所占的内存大小并非元素本身类型大小之和。对于自然对齐而言:
对于各成员变量来说,存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数,各成员变量在存放的时候根据在结构中出现的顺序依次申请空间, 同时按照上面的对齐方式调整位置, 空缺的字节自动填充。
对于整个结构体来说,为了确保结构的大小为结构的字节边界数(即该结构中占用最大的空间的类型的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
所以一般我们在定义结构体时定义各元素的顺序也会影响实际结构体在存储时的整体大小,把大小相同或相近的元素放一起,可以减少结构体占用的内存空间。
除了自然对齐的内存大小,我们也可以设置自己需要的对齐大小,我们称之为对齐系数,如果结构内最大类型的字节数小于对齐系数,结构体内存大小应按最大元素大小对齐,如果最大元素大小超过对齐系数,应按对齐系数大小对齐。
对齐系数大小的设定可以使用下列方法:
#pragma pack (16)使用预编译器指令要求对齐。#pragma pack()恢复为默认对齐方式。
__attribute__ ((aligned (16)))//GCC要求对齐
__declspec(intrin_type) _CRT_ALIGN(16)//Microsoft Visual C++要求对齐
联合的内存对齐方式与结构类似。