对内存对齐的理解

先介绍一篇有用的文章,来自外网,这里简单翻译一下,

什么是数据对齐?

在编程语言中,一个数据对象(变量)有两个属性;它的值和存储位置(地址)。数据对齐是指数据的地址可以被1、2、4或8整除。换句话说,数据对象可以有1字节、2字节、4字节、8字节对齐或任何幂2. 比如一个数据的地址是12FEECh(十进制1244908),那么就是4字节对齐,因为地址可以被4整除。(你可以除以2或1,但是4是可整除的最高数。)

CPU 不会一次读取或写入一个字节。相反,CPU 一次以 2、4、8、16 或 32 字节块访问内存这样做的原因是性能 ------ 访问 4 字节或 16 字节边界上的地址比访问 1 字节边界上的地址快得多。

 

也就是说在某个地址上写入数据时,如果该地址不是对齐的地址,那CPU就要操作两次才能拿到完整的数据,所以数据慢了。

如何判断当前地址是否为所要获取字节的对齐地址呢? 

比如,使用 AVX 算法时,CPU 可以一次性从当前地址上读取 32 字节的数据,为了保证高效性,内存对齐是必要的,那么我们就可以依靠


#define PTR_ADDR(p) ((unsigned long)p)
if (PTR_ADDR(address) % 32 == 0) {
    // 内存是对齐的
  }

在二进制上至少需要 0010 0000 的倍数才行, 0010 0000 换成十进制是 32,等于 0110 0000,1110 0000 这样的都是可以的,换成 16进制就是 0x20 的倍数

例子:How Do I check a Memory address is 32 bit aligned in C

手动创建对齐数组,

float __declspec(align(32)) out[8] = {}; // 在 windows 上创建 32 个字节对齐的地址

 

posted @ 2021-08-12 21:30  strive-sun  阅读(170)  评论(0编辑  收藏  举报