如何在 Linux 中分配满足分页和缓存要求的内存?

Posted

技术标签:

【中文标题】如何在 Linux 中分配满足分页和缓存要求的内存?【英文标题】:How can I allocate memory in Linux that meets paging and cacheability requirements? 【发布时间】:2011-04-17 10:16:14 【问题描述】:

我想为一个大型数组分配空间,该数组在程序结束之前都是只写的。出于这个原因,我不在乎它是否被缓存。

我也想非常频繁地访问它,所以我不想多次浏览页面。出于这个原因,我希望它被分配在一个大页面中(例如 4M)。

那我怎么...

...请求内存不可缓存或直写? ...请求将内存放在大页面中?

我在 Linux 中工作。

【问题讨论】:

您确定要使其不可缓存吗?也许你想要一个非临时存储:***.com/questions/37070/… @Adrian:非临时性也不错。如何告诉编译器生成非临时存储? 我已经有一段时间没有这样做了,但是这里有一些起始链接 - ***.com/questions/661338/sse-sse2-and-sse3-for-gnu-c 请记住,“只写”并不意味着缓存没有用。对于通常的“回写”内存类型,写入意味着读取:在写入之前,CPU 将相应的行放入 L1 缓存中,然后写入发生在 L1 中。因此,如果您对同一个缓存行进行多次写入,您真的想要 L1 中的行,因为它允许写入非常快地完成。如果您不缓存写入(例如,通过使用 NT 存储或 WB 内存),则每次写入(或者,在野兽,缓存行的所有写入)都必须一直到内存,这需要 100 个周期. ...所以你真的希望这种行为只用于你只写一次的内存,或多或少(或者至少写得不频繁以至于缓存行为不相关)。您还希望一次在缓存行中写入连续的位置,以至少使用写入组合功能,以便一次将一个缓存行发送到内存,而不是一次发送几个字节。 【参考方案1】:

如果强制一直写入 RAM,禁用缓存听起来会使您的写入速度变慢。我不确定我是否会尝试这样做。

要实际使用大页面,我建议关注HugeTLB - Large Page Support in the Linux Kernel。它包含一个如何通过共享内存段使用大页面的示例。

【讨论】:

【参考方案2】:

对于透明的大页面,只需分配一个 4M 对齐的缓冲区即可。使用aligned_allocposix_memalign 获取指针,您可以使用free。 (请注意,如果缓冲区大小不是对齐的倍数,aligned_alloc 必须失败。/facepalm)。

根据您对/sys/kernel/mm/transparent_hugepage/defrag 的设置,您可能需要在缓冲区上使用madvise(MADV_HUGEPAGE) 以强烈鼓励内核使用大页。

还要注意 x86-64 使用 2M 大页面。 x86-32 使用 4M 大页面。如果您想要两者的简单解决方案,对齐到 4M 就可以了。


请求内存不可缓存或直写?

AFAIK,您不能通过普通的 Linux API 轻松做到这一点。 NT stores 适用于正常的回写内存,因此请改用它。 (它们会覆盖内存类型并且是弱排序的缓存绕过)。

但是,如果您不是一次写入完整的缓存行,那么您肯定需要缓存写入。特别是如果存在任何空间或时间局部性,但即使没有,让存储缓冲区完成其工作(隐藏缓存未命中存储的延迟)也是一件好事。

【讨论】:

以上是关于如何在 Linux 中分配满足分页和缓存要求的内存?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 中分配大的连续内存区域

小峰mybatismybatis分页和缓存

如何在 C 中分配和释放对齐的内存

在linux中分配物理内存缓冲区

linux内核内存分配

在 Linux 内核中分配用户空间内存