坚持了解内存对齐

时间:2019-05-18 03:09:35

标签: c++ memory-management memory-alignment

The code分配保存width * height映像的内存如下:

  const size_t alignment = 64;
  size_t space = width * height * bytes_per_pixel + alignment;
  rawdata = new unsigned char[space];
  //typedef unsigned long int uintptr_t
  uintptr_t ptr = reinterpret_cast<uintptr_t>(rawdata); 
  uintptr_t aligned = (ptr - 1u + alignment) & -alignment; 
  data = reinterpret_cast<unsigned char *>(aligned);

似乎在rawdata(即最初分配的内存)上执行了64字节的对齐,这生成了data指向的对齐内存。但是,令我困惑的是:

uintptr_t aligned = (ptr - 1u + alignment) & -alignment

有人可以帮我吗?

1 个答案:

答案 0 :(得分:3)

该计算确保地址与给定的数量对齐(必须为2的幂)。这意味着对齐方式为n时最低的2^n位必须为零。

让我们以二进制形式进行操作。假设我们得到了一个随机指针,对齐方式为16个字节,而我们希望它对齐为64字节并进行计算。 (这是假设两个的补码,顺便说一句,虽然不能保证,但实际上是标准的):

address = ...1101010000
address - 1 -> ...1101001111
address + 64 -> ...1110001111
-alignment -> ...1111000000
address & -alignment -> ...1110000000

实际上,由于-alignment的所有位都比对齐点低零,因此它找到了可对齐对齐的最小值。通过添加alignment-1(它是对-alignment的取反)来确保它比原始指针大,所有高位都是零,低位是1。

如果地址已经对齐怎么办?然后,由于原始指针的最低位为零,因此计算得出原始指针,您将所有最低位均设为1,然后将它们相加。