坚持理解记忆对齐

stuck on understanding memory alignment

本文关键字:对齐 记忆 坚持      更新时间:2023-10-16

分配包含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);

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

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

谁能帮我?

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

让我们用二进制来做。假设我们得到一个随机指针在 16 字节对齐,而我们希望它以 64 字节对齐并计算。(这假设了两个的补码,顺便说一下,这不能保证,但事实上是标准):

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

因此,实际上,它找到的最小值可以通过对齐整除,因为-alignment所有位都低于对齐点为零。它还通过添加alignment-1来确保它比原始指针大,这是-alignment作为位的否定,即所有顶部位为零,但较低的位为一。

如果地址已经对齐怎么办?然后计算结果为原始指针,因为它的最低位为零,您将所有最低位设置为一,然后 AND 它们消失。