【问题标题】:C/C++ - posix_memalign()C/C++ - posix_memalign()
【发布时间】:2011-03-23 04:06:18
【问题描述】:

我阅读了一些关于缓存未命中优化的内容,并了解了这个 stdlib 函数。它会进行某种内存对齐以进行优化,但是 any1 可以帮我解释一下这个函数的真正作用吗?它需要 3 个参数:void* * mempr、size_t 对齐、size_t 大小

我不明白的部分是文档的含义

"分配的 size 字节对齐在一个 alignment指定的边界..."

我从阅读中理解的是分配一块大小为size的内存块的函数,但在那之后,我不明白“边界”是什么意思...是内存块被分解成较小的块,大小为alignment

这是文档:http://www.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html

【问题讨论】:

    标签: c++ memory alignment


    【解决方案1】:

    我阅读了一些关于缓存未命中优化的内容,并了解了这个 stdlib 函数。它会进行某种内存对齐以进行优化,但是任何人都可以帮我解释一下这个函数的真正作用吗?

    该函数的主要目的是分配一个与页面大小对齐的缓冲区。这很少用于性能 - 通常是因为需要适合设备驱动程序/直接硬件访问的缓冲区。

    编译器本身已经解决了性能与内存对齐问题的最大份额。例如。所有基本类型 - char、short、int、long - 已经在它们的 自然对齐 上定位在内存中(或结构内部):变量(或结构的字段)的地址可以被大小整除的变量。为了实现这一点,使用了 padding。 (例如,在char a; int b; 中,在a 之后,将添加sizeof(char)-sizeof(int) 字节以确保b 的地址与sizeof(b) 对齐。)

    我不明白他们所说的“边界”是什么意思...是内存块被分解成具有对齐大小的更小的块吗?

    硬件设备(尤其是非 PCI 设备)通常将内存视为 N 个字节上的块,并且一次只能访问 N 个字节。 Boundary 在上下文中表示块的开始,如“块边界”。

    现在,我很不情愿地提到对齐对性能的影响。请记住,过早的优化是万恶之源。这些技巧是高度平台 CPU特定的,因此通常不应该使用:

    • 当您想要提高数据的局部性时,在某些情况下需要页面大小对齐。将虚拟地址转换为物理 RAM 位置的 CPU 维护缓存。更少的页面代码访问,更少的 CPU 压力。 (大多数操作系统已经尝试优化应用程序的页面布局,以尽量减少 virt 到 phys 地址转换的开销。)如果您知道您经常访问的结构适合单个页面,那么建议将其放入页面中对齐的存储,以保证它将包含在单个页面中。 malloc() 不提供保证,并且可能会放置结构,使其从一页开始并在另一页结束 - 跨越页面边界 - 从而占用 TLB 中的两个条目而不是所需的单个条目。 (How to find page size.)

    • Cache line 对齐。虽然应用程序可以以字节为单位寻址内存,但实际上 CPU 只能访问物理 RAM 块,通常称为“高速缓存行”。这是物理 RAM 的最小可寻址单元。通过利用结构的高速缓存行对齐,旨在最大限度地减少代码的高速缓存足迹和高速缓存未命中。 DRAM/DDR 的缓存线大小为 16 字节。如果平台的内存控制器具有更宽的数据总线并并行访问多个内存模块,则它可以更大(32 或 64 字节)。相同的逻辑(至于页面对齐)也适用于此处:如果您输入例如结构字段通常作为一个组一起访问,在缓存行大小上对齐,您可以大大减少数据的缓存占用。最简单的例子是std::map< struct aaa *, void * >。如果struct aaa 包含很多字段,为了最小化缓存占用,可以将所有用于比较的字段(关键字段)放在结构的开头。如果关键字段分布在结构上,则比较在最坏的情况下会触及每个关键字段的高速缓存行。如果关键字段在结构的开头组合在一起,那么比较可能会触及更少的缓存行。更少的缓存行数据需要,更多的缓存留给应用程序的其余部分。缓存行大小通常不适用于应用程序,但可以通过utilizing various tricks 找到。

    我刷了很多小细节以保持相对简短。如果您想了解更多信息,建议阅读一些 CPU 手册。例如。英特尔有相当好的developer's manuals

    【讨论】:

    • @jaunt,是的,时光飞逝。只需谷歌“英特尔开发人员手册”。现在的版本好像叫做《Intel(R) 64 and IA-32 Architectures Developer's Manual》。
    • 我不认为页面边界对齐是主要目的:缓存行对齐更为重要。它有助于向量指令和预取流。
    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 2015-02-13
    • 2022-06-10
    • 2014-11-12
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多