51

我构建了两个程序,一个使用malloc,另一个使用mmap. using 的执行时间mmap比 using 少得多malloc

例如,我知道,当您使用时,mmap请避免对系统进行读/写调用。并且内存访问更少。

mmap但是使用over的优势还有其他原因malloc吗?

非常感谢

4

6 回答 6

16

伙计们,与通常认为的相反,mmap 确实是一个类似于 malloc 的内存分配函数。

mmaped文件是它的一种用途..您可以将其用作内存分配函数,将-1作为文件描述符..

所以..常见的用途是对小对象使用 malloc ,对大对象使用 mmap ..

这是一个很好的策略..

我使用 alloca() 仅用于函数范围的变量..

于 2010-10-21T22:31:39.050 回答
16

我假设您指的是使用mmapmalloc从文件中读取数据。在那种情况下,你几乎明白了要点:

  • 使用fread/fwrite你必须对操作系统进行多次调用。
  • 使用mmap您似乎可以在一次操作中访问整个文件。这并不完全正确,因为操作系统可能一次将文件映射一个内存页,但它仍然要快得多。
于 2009-11-15T23:44:57.467 回答
15

mmap实际上并不会将文件加载到内存中,因此加载速度会更快,但编辑速度会更慢。

还有一点就是mmap不使用任何内存,但是会占用地址空间。在 64 位机器上,大部分内存地址空间都没有内存,所以你可以加载你不想加载的大文件,比如 5GB malloc

于 2009-11-15T23:45:51.350 回答
12

malloc 和 mmap 有时都很慢。这主要取决于使用模式:

mmap:内核分页子系统以页面大小为单位工作。这意味着,如果您想从文件中读取整个页面并想要重复执行此操作(良好的本地化),那么使用 mmap 就可以了。相反,如果您映射该 5 Gb 文件并进行分散访问,您将有很多内核交换页面进出。除了实际的 I/O 之外,页面管理还需要一些时间。如果您担心延迟,请避免使用这种访​​问模式,因为 Linux 页面回收机制往往是突发的并且会导致明显的延迟,并且缓存中毒会减慢其他进程。

malloc:当您需要不是页面大小单位的内存时,这很好。但你不能理智地做 mlock() 之类的事情。就 I/O 而言,速度很大程度上取决于您的操作方式。fread/fwrite 可以在后台映射页面,或者在用户空间中进行缓冲。本地化访问将相当快。读/写直接通过内核,因此小的分布式访问仍然会由于缓存未命中而导致I/O,但是从内核->用户空间传输的实际数据会稍微少一些。我不知道这是否可以衡量。

除非 mlock()'ed,用户页面可以随时换出/写回。这也需要时间。因此,在内存很少的系统上,映射最少内存的变体将获胜。对于 Linux 内核,每个系统的内存都太少,因为未使用的页面用于缓存 I/O,如果内存使用或 I/O 是突发的,内核可能需要相当长的时间才能使它们可用。

于 2013-03-02T05:16:56.800 回答
3

mmap 实际上并不读取文件。它只是将其映射到地址空间。这就是它如此之快的原因,在您实际访问该地址空间区域之前,没有磁盘 I/O。

malloc 只是地址空间到内存的映射

于 2009-11-15T23:49:21.950 回答
0

通过 mmap 不授予 RAM。地址空间被授予。

当访问地址空间时,就会出现页面错误。在页面大小的页面错误期间,通常为 4096 字节,提供 RAM。

还提供了 RAM 内容。如果通过文件支持地址空间,则将出现文件内容。如果通过 MAP_ANONYMOUS 支持地址空间,则出现零初始化 RAM。

由以上两个恩惠描述。首先,可以完全按照需要初始化 RAM。其次,直到没有提供所需的 RAM。

对于 malloc 小于 2 兆字节的地址请求,程序中断被扩展。虽然提供接近程序中断的地址,但程序中断不能签约。因此,释放给内核的 RAM 可能不会返回。一个类比如下。穿鞋前可以脱袜子吗?

通过对内核 RAM 的 munmap 调用立即返回。通过 mmap 和 munmap 使用交换概率被减轻。由 malloc 程序中断扩展交换概率被激发。

通过 malloc 可以分配小于页面大小的内存。不连续的记忆就变成了。内核内存也可以碎片化。两者都不完美。

内核 RAM 可以在任何空闲处理器上进行碎片整理。创建 2 兆字节大小的透明大页面。与提供 2M 的 512 页错误相比,当通过单个页错误可以提供 2M 时,性能显着提升。

通过 mmap,至少存在一个值得注意的祸根。对于支持管道文件描述符的 mmap,可以使用。不变成错误。但是,在内存地址中,管道提供的数据不会出现。

但是,如果使用 MAP_ANONYMOUS,则可以从管道文件描述符到 mmap 提供的地址中读取数据。虽然效率不如预期的结果。通过 lseek 失败返回和 errno 可以识别管道附加文件描述符。

通过可以寻址整个兆字节并运行基于磁盘的操作系统的计算机,那么 malloc 的使用是必不可少的。如果使用 C 库提供的 getline 函数,则可能会使用 malloc 和 free。

在内核控制的操作系统而不是 mmap 上,为什么要使用 malloc?与 malloc 相比;mmap 看起来很复杂?要调用 munmap,还必须提供先前请求的地址空间量。malloc 使用更便携?malloc 好像更方便?

然而,如果需要性能,则使用 mmap。

最后但并非最不重要的一点是,如果 MAP_SHARED 则可以与后代进程共享数据。避免 pthreads 是最重要的。有时克隆也可以避免。

尽管是主观的,变量分配方法列在最不受欢迎的列表如下:寄存器/堆栈;地图;全球的; 马洛克。由每个不同的利弊成为。通过足够复杂的程序;使用了三种或可能所有四种方法。

于 2016-03-25T03:12:01.910 回答