【问题标题】:Slow memory allocation in OSXOSX 内存分配缓慢
【发布时间】:2015-09-06 12:07:22
【问题描述】:

我正在尝试找出我在 OSX 中遇到的内存分配问题。 如果我正常编译运行下面的代码,运行速度会很快。

#include <sys/mman.h>
#define SIZE 8 * 1024 * 1024

int main(int argc, char const *argv[]) {
  for (int i = 0; i < 50000; ++i) {
    mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  }
  return 0;
}

但是,如果我编译相同的代码但链接到某个库(即:clang -o test test.c -lpcre),它将随机运行快速(30 毫秒)或非常慢(18 秒)。

请注意,我什至没有使用库,只是链接。我还注意到,这似乎不会发生在任何库中。

我正在运行 OSX 10.10.3。有什么想法吗?

【问题讨论】:

  • 我可以重现该问题。用iprofile -timeprofiler 运行它表明所有时间都花在__mmap(从mmap 调用)。检查mmap 的结果表明调用总是成功的。

标签: c macos mmap


【解决方案1】:

如果您不需要初始化内存,则使用 malloc() 会更有效,因为您使用 mmap() 不仅为您的进程分配 8 MB 的内存,而且还初始化它。

在 OS X 上,malloc() 和 mmap() 在内部都使用 mmap() 系统调用(系统调用号 197 - http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/kern/syscalls.master),它要求内核将虚拟内存映射到物理内存记忆。

【讨论】:

  • malloc() 还必须要求操作系统分配页面,但它以更大的块进行。但在我的情况下,我总是需要为 mmap() 分配大缓冲区应该更有效。实际上我尝试使用 malloc() 并且它总是运行得很慢。你有一个 malloc() 优于 mmap() 的例子吗?
  • @waj 我只是在这方面做了一些研究,在 OS X 上你是对的,我已经编辑了我的答案。 mmap() 和 malloc() 在内部都使用 mmap() 系统调用。我的印象是 malloc() 会在内部使用 brk() 系统调用,它只是改变数据段的大小,但这不正确。
  • @waj 在该示例中,malloc() 返回比 mmap() 慢实际上没有意义,因为 malloc() 不会初始化分配的内存。但是,这些函数的速度是高度特定于实现的。
  • 感谢您的研究。我仍在寻找一种分配这些大块内存而不预先初始化内容的好方法。 mmap 在 Linux 中运行良好,但在 OSX 中却不行。
  • 我尝试使用此处描述的 vm_allocate:developer.apple.com/library/mac/documentation/Performance/…。但我也遇到了我在最初问题中描述的相同问题。
【解决方案2】:

当然。这是一个想法。每个人和他的狗通过调用 malloc 来分配内存。在 MacOS X 的历史上,从来没有人使用过 mmap 来分配内存。考虑到这一点,猜测哪些功能已被优化到最大,而 MacOS X 的设计者对哪些功能一点也不在乎速度。使用已经优化的那个。

【讨论】:

  • 在我的情况下,我需要延迟分配内存页面,这就是我尝试使用 mmap 的原因。我尝试了两者,而不仅仅是猜测。你知道一些在 OSX 中分配虚拟内存空间而不分配页面直到使用的方法吗?
  • 顺便说一句,即使我对 mmap 的使用不正确,我仍然想知道为什么当我链接到某个库时它的行为会很奇怪。
  • 这里有个想法:malloc 使用mmap,所以它应该不会比直接调用mmap 快。
【解决方案3】:

这只是内核中的一个错误,其他人也遇到过。内核中用于查找未使用的地址空间块进行分配的代码使用了低效的搜索算法。

我怀疑它似乎取决于您是否链接库的原因是动态加载程序 (dyld) 必须映射这样的库,并且有时会使内核的 VM 内务管理数据进入触发搜索效率低下的状态。并非每次运行都发生这种情况的原因可能与地址空间布局随机化 (ASLR) 有关。

我鼓励您就此向 Apple 提交错误,特别是因为您有一个很好的简单测试用例。 (它可能会因为重复而被关闭,因为我相信你不会是第一个提交它的人。不过,每个新的错误报告都可以帮助隔离它并提高它在 Apple 内的优先级。)

【讨论】:

  • 您是否有任何关于其他人也遇到过的参考
  • 例如在this thread中关于git的实现。还有其他例子。只需在网上搜索“os x slow mmap”或类似内容。
  • 我填补了这个错误。我希望他们在未来的版本中修复它!当这种事情发生在我身上时,我试着认为这一定是我做错了什么。但在这种情况下,在缩小可能性之后,似乎除了内核错误别无选择。
  • @waj 你能把你的bug的链接贴出来吗?只是想跟踪它的状态。
猜你喜欢
  • 2012-05-07
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2011-07-25
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
相关资源
最近更新 更多