坚持理解内存对齐
stuck on understanding 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
谁能帮帮我?
该计算确保地址与给定的数量对齐(必须是 2 的幂)。这意味着当对齐为 2^n
.
时,最低 n
位必须为零
让我们用二进制来做。假设我们得到一个以 16 字节对齐的随机指针,而我们希望它以 64 字节对齐并进行计算。 (这假定了二进制补码,顺便说一下,这不能保证,但事实上是标准的):
address = ...1101010000
address - 1 -> ...1101001111
address + 64 -> ...1110001111
-alignment -> ...1111000000
address & -alignment -> ...1110000000
因此实际上它找到了可被对齐整除的最小值,因为 -alignment
在对齐点下方的所有位都为零。它还通过添加 alignment-1
来确保它大于原始指针,这是 -alignment
作为位的否定,即所有高位为零但低位为 1。
如果地址已经对齐怎么办?然后计算结果为原始指针,因为它的最低位为零,您将所有最低位设为 1,然后将它们移除。
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
谁能帮帮我?
该计算确保地址与给定的数量对齐(必须是 2 的幂)。这意味着当对齐为 2^n
.
n
位必须为零
让我们用二进制来做。假设我们得到一个以 16 字节对齐的随机指针,而我们希望它以 64 字节对齐并进行计算。 (这假定了二进制补码,顺便说一下,这不能保证,但事实上是标准的):
address = ...1101010000
address - 1 -> ...1101001111
address + 64 -> ...1110001111
-alignment -> ...1111000000
address & -alignment -> ...1110000000
因此实际上它找到了可被对齐整除的最小值,因为 -alignment
在对齐点下方的所有位都为零。它还通过添加 alignment-1
来确保它大于原始指针,这是 -alignment
作为位的否定,即所有高位为零但低位为 1。
如果地址已经对齐怎么办?然后计算结果为原始指针,因为它的最低位为零,您将所有最低位设为 1,然后将它们移除。