我们啥时候需要使用 posix_memalign 而不是 malloc?
Posted
技术标签:
【中文标题】我们啥时候需要使用 posix_memalign 而不是 malloc?【英文标题】:When do we need to use posix_memalign instead of malloc?我们什么时候需要使用 posix_memalign 而不是 malloc? 【发布时间】:2011-09-18 15:08:34 【问题描述】:好像posix_memalign
让你选择一个自定义的alignment
,但是什么时候需要呢?
malloc
已经在内部完成了对齐工作。
更新
我问这个的确切原因是因为我看到nginx这样做了,ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
,这里NGX_POOL_ALIGNMENT
定义为16
,nginxs.googlecode.com/svn-history/trunk/src/core/ngx_palloc.c
【问题讨论】:
【参考方案1】:基本上,如果您需要比 malloc 更严格的对齐方式。 Malloc 通常返回一个对齐的指针,它可以与任何原始类型一起使用(通常,在普通桌面机器上为 8 个字节)。
但是,有时您需要在其他边界上对齐内存,例如 4K 对齐等。在这种情况下,您需要memalign
。
你会需要这个,例如,
编写内存管理器(如垃圾收集器)时。在这种情况下,有时在较大的块大小上使用对齐的内存很方便。这样,您可以将所有对象共有的元数据存储在分配区域底部的给定块中,并通过屏蔽对象指针的最低有效位来访问它。 与硬件接口时(我自己从未这样做过,但 IIRC,某些类型的块设备需要对齐的内存)。有关详细信息,请参阅 n.m. 的答案。【讨论】:
@Dirk,这似乎没有回答 什么时候我们需要。 更多示例:SIMD 类型可能需要比malloc
提供的更多对齐。为性能发挥非常花哨技巧的代码可能需要与缓存行大小相对应的对齐 - 如果您正在编写动态链接器(即将可执行文件加载到内存中的代码),这可能是最常见的,您正在加载的代码可能需要它的功能在缓存行边界上对齐。
@Steve Jessop,如果16*1024
的内存大小和16
对齐而不是默认的8
,我们会受益吗?
@Steve: §7.20.3 "如果分配成功,返回的指针经过适当对齐,以便可以将其分配给指向任何类型的对象的指针,然后使用访问这样的对象......”(强调)。实际上,这意味着在具有 128 位 SIMD 单元的现代 64 位系统上,malloc
返回对齐到 16 字节边界的内存,即使指针只有 8(或 4)字节宽。
@Dietrich:这可能是它的意思,但这不是实现的实际作用。你可以忍受这个,或者你可以声明 MSVC 和 GCC 不符合并拒绝为他们写。在这种情况下,您可能需要与 C 编程不同的工作线;-) 据我所知,退出的原因是,由于 SIMD 类型是标准的扩展,因此允许实现“破坏”代码它通过引入内存超级对齐的附加要求来使用它们。【参考方案2】:
各种硬件可能有malloc
无法满足的对齐要求。 Linux 手册页给出了一个这样的例子,我引用:
在许多系统上都有对齐 限制,例如关于用于的缓冲区 直接块设备 I/O。 POSIX 指定 pathconf(path,_PC_REC_XFER_ALIGN) 调用 这告诉我们需要什么对齐。
【讨论】:
【参考方案3】:几个用途:
某些处理器的指令仅适用于以大于或等于缓冲区大小的 2 的幂对齐的数据 - 例如,ffts(快速傅立叶变换)中使用的位反向寻址指令。
将数据与缓存边界对齐,以优化多处理应用程序中的访问,以便两个处理器不会同时访问同一缓存行中的数据。
基本上,如果您不需要进行荒谬的优化级别和/或您的硬件不要求数组位于特定边界上,那么您可以忘记 posix_memalign。
【讨论】:
cache boundaries
和 cache line
是什么意思?【参考方案4】:
据我所知,posix_memalign
的唯一好处是:
-
为特定于硬件的目的分配页面对齐(通常为 4096 或更大对齐)内存。
Evil hack 将指针 0 的低
N
位保持在低位,这样您就可以在低位存储 N
-bit 整数。 :-)
【讨论】:
@compile-fan,如果你指向的对象都大于,比如说,4字节,并且在4字节边界上对齐,你可以从底部窃取2位如果在将指针用作指针之前总是将它们屏蔽为零,则指针。 我问这个的确切原因是因为我看到nginx这样做了,ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
,这里NGX_POOL_ALIGNMENT
被定义为16
,nginxs.googlecode.com/svn-history/trunk/src/core/ngx_palloc.c
听起来 nginx 正在管理自己的内存池,基本上是在自己分配的块之上复制malloc
,并希望确保它可以提供最多 16 个字节的对齐。我不知道为什么它会关心这个,因为malloc
已经为任何 C 类型提供了足够的对齐,如果你使用了由malloc
获得的块并且在切片时没有应用未对齐的偏移量,它将保持一致。从过去关于nginx的一系列问题来看,我怀疑nginx的作者是否理解他们首先使用memalign
的原因......以上是关于我们啥时候需要使用 posix_memalign 而不是 malloc?的主要内容,如果未能解决你的问题,请参考以下文章
ARM GCC 中对 posix_memalign 的未定义引用
无法在 Visual Studio 2010 中使用函数 posix_memalign