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

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

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

那我怎么...

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

我在 Linux 中工作。

【问题讨论】:

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

标签: linux memory-management


【解决方案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 适用于正常的回写内存,因此请改用它。 (它们会覆盖内存类型并且是弱排序的缓存绕过)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-11
      • 2012-01-12
      • 2015-02-08
      • 2020-05-05
      • 1970-01-01
      • 2018-09-07
      • 2017-11-18
      • 2012-10-30
      相关资源
      最近更新 更多