C / C ++ - posix_memalign()

时间:2010-07-30 09:48:02

标签: c++ memory alignment

我对缓存未命中优化做了一些阅读,并开始了解这个stdlib函数。它为优化做了某种内存对齐,但是可以帮助我解释一下这个函数到底有什么用吗?它需要3个参数: void * * memptr,size_t alignment,size_t size

我没有得到的部分是文档的含义

  

“分配大小字节对齐a    alignment 指定的边界......“

我从阅读中理解的是分配大小为 size 的内存块的功能类型,但在此之后,我没有得到“boundary”的意思 ...是否将内存块分解为大小为 alignment 的较小块?

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

1 个答案:

答案 0 :(得分:9)

  

我对缓存未命中优化做了一些阅读,并开始了解这个stdlib函数。它为优化做了某种内存对齐,但是可以帮助我解释一下这个函数真正做了什么吗?

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

性能与内存对齐问题的Lion分享已由编译器本身解决。例如。所有基本类型 - char,short,int,long - 已经在自然对齐的内存(或结构内部)中定位:变量(或结构的字段)的地址可以被大小整除变量。为此,使用填充。 (例如,char a; int b;之后的asizeof(char)-sizeof(int)字节将被添加,以确保b的地址在sizeof(b)上对齐。)

  

我没有得到“边界”的含义......是否将内存块解析为具有对齐大小的较小块?

H / W设备(特别是非PCI设备)经常将内存视为N个字节上的块,并且一次只能访问N个字节。上下文中的 Boundary 表示块的开始,如“块边界”。

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

  • 在某些情况下,如果要改善数据的位置,则需要页面大小对齐。将虚拟地址转换为物理RAM位置的CPU维护缓存。较少的页面代码访问,减少了施加在CPU上的压力。 (大多数操作系统已经尝试优化应用程序的页面布局,以最大限度地减少物理地址转换的开销。)如果您知道您经常访问的结构适合单个页面,那么建议将其放入页面中对齐存储以保证它将包含在单个页面中。 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