什么是对齐的内存分配?

时间:2010-10-22 05:05:10

标签: malloc

我也想知道glibc malloc()是否这样做。

4 个答案:

答案 0 :(得分:58)

假设你有结构。

struct S {
    short a;
    int b;
    char c, d;
};

如果没有对齐,它将在内存中布局(假设采用32位架构):

 0 1 2 3 4 5 6 7
|a|a|b|b|b|b|c|d|  bytes
|       |       |  words

问题在于,在某些CPU架构中,从内存加载4字节整数的指令仅适用于字边界。因此,您的程序必须使用单独的指令获取b的每一半。

但如果记忆的布局如下:

 0 1 2 3 4 5 6 7 8 9 A B
|a|a| | |b|b|b|b|c|d| | |
|       |       |       |

然后访问b变得简单明了。 (缺点是需要更多内存,因为填充字节。)

不同的数据类型具有不同的对齐要求。 char通常为1字节对齐,short为2字节对齐,4字节类型(intfloat和指针位于32-位系统)要4字节对齐。

C标准要求

malloc返回一个针对任何数据类型正确对齐的指针。

x86-64上的

glibc malloc返回16字节对齐的指针。

答案 1 :(得分:6)

Alignment要求指定可以将哪些地址偏移分配给哪些类型。这完全取决于实现,但通常基于字大小。例如,某些32位体系结构要求所有int变量以四的倍数开始。在某些体系结构上,对齐要求是绝对的。在其他人(例如x86)上藐视它们只会带来性能损失。

malloc需要返回适合任何对齐要求的地址。换句话说,返回的地址可以分配给任何类型的指针。从C99§7.20.3(内存管理功能):

  

如果分配则返回指针   成功适当地对齐以便   它可以被分配给指向任何的指针   对象的类型然后用于访问   这样的对象或这样的数组   分配的空间中的对象(直到   空间明确解除分配。)

答案 2 :(得分:1)

如果您有特定的内存对象需求(对于特定的硬件或库),您可以检查非便携式内存分配器,例如_aligned_malloc()memalign()。这些可以很容易地在“便携式”界面后面抽象,但不幸的是非标准。

答案 3 :(得分:1)

malloc()文档说:

[...] the allocated memory that is suitably aligned for any kind of variable.

对于您在C / C ++中所做的大多数事情都是如此。但是,正如其他人所指出的那样,存在许多特殊情况并需要特定的对齐。例如,英特尔处理器支持256位类型:__m256malloc()肯定不会考虑这种类型。

同样,如果要为要分页的数据分配内存缓冲区(类似于mmap()返回的地址等),那么你需要一个可能非常大的对齐,这会浪费大量的内存如果malloc()返回的缓冲区始终与这些边界对齐。

在Linux或其他Unix系统下,我建议你使用posix_memalign()函数:

int posix_memalign(void **memptr, size_t alignment, size_t size);

这是人们想要用于满足此类需求的最新功能。