通常我们说 32 位和 64 位是指字长 :CPU 一次可处理 64bit 数据,地址线宽度是 64 位,内部数据线宽度是 64 位(一次可读取 64bit 数据);结构体内存对齐是针对数据线宽度来说的,64 位机器上按照 8 字节对齐,可以提高访存效率;设想如果一个 int 类型不对齐时,它的 4 个字节刚好在两个连续的 8 字节中间,那么访问这个 int 时就需要读两次 8 字节,分别截取这个 int 的高低两个字节,再拼起来;这里的内存对齐相当于是内存空间换访存时间
stackoverflow 中这个问题下有一个解答非常好, c - Is 8-byte alignment for “double” type necessary? - Stack Overflow ,我在这里简单描述一下要点:
- 首先数据总线可能是 8 字节宽,那么它一次只能从内存中获得 8 字节,如果没有进行内存对齐,那么读取一个 8 字节的变量,可能就需要两次才能完成。
- 高速缓冲同样的也可能是 4 字节或者 8 字节,能在一个 cache line 里放下的数据放到两个里面就有点蠢了
- 一个内存页通常是 4096 字节,如果一个对象没有进行内存对齐,放在了两个页中间,首先面临的问题可能就是缓冲没有命中,这会导致性能的降低,另一方面,cpu 会在真正执行到加载数据的指令之前就提前尝试加载,这当然要进行一次检查,防止将下面的指令即将改变的内存提前加载了,如果没有内存对齐,对象分布在两个内存页上,这样的检查就需要有两次。