首先,我们介绍一下结构体内存对齐的规则:
1.第一个成员在与结构体偏移量为0的地址处。
2.其他成员变量要对其到某个数字(对齐数)的整数倍的地址处。
注:对齐数=编译器默认的一个对齐数与该成员大小的较小值(vs中默认的对齐数为8)
3.结构体总体大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处。结构体整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
我们来看这样一组代码:
struct test{
int a; //4个字节
char b; //1个字节
int c; //4个字节
}test;
我们使用32位的编译器打印出来,发现它的结构体内存大小是12,这是为什么呢?
因为,编译器为了编译速度的提升,就会按照4个4个的开始扫描,例如下图:
所以,这个结构体的大小就是12字节。至于为什么编译器要这样做,这就要谈一谈计算机硬件的相关知识了。
我们知道计算机的一个主板上有两个channel(通道),一个channel有两个DDIM(内存条),一个内存条有两个面,也就是rank1和rank2。这里我们先看一个单面的rank,这一个里面有四个内存颗粒,那么,现在要存储一个数据叫做int a,是存储在一个颗粒里面还是四个颗粒里面呢?
答案是四个,因为cpu想同时取出4个字节的数据也就是32位,肯定会充分发挥并行传输数据的能力,同时与四个颗粒进行数据交互,速度就会比与一个颗粒交互要快。
每个颗粒chip里面有8个bank,每次同时从8个bank中取一位数据,为了节约地址总线位数,每次都是从每个bank的同一行、同一列里读取、操作数据,其次,在四个颗粒中的相对位置也是相同的,每一字节的每一位在每个chip的bank里位置也都是相同的(相同行、相同列)。