当前位置: 首页 > 知识库问答 >
问题:

mmap如何提高文件读取速度?

司空宗清
2023-03-14

与malloc'相同大小的内存和手动读取整个文件到malloc'区域相比,这有什么不同?

共有1个答案

吴宏扬
2023-03-14

mmap的工作方式不同。它具有预见性,并适应程序的访问模式。此外,还可以通过madvise设置特定的策略,以进一步优化使用情况。

有关mmap如何在需求分页环境中工作的更深入的讨论,请参见我的答案:哪些段受写时复制的影响?因为它还讨论了mmap的使用

mmap是通过execveet执行程序的命脉。艾尔。所以,你可以打赌它很快。顺便说一句,讽刺的是malloc实际上也使用匿名mmap

对于mmap,内存区域的后备存储是文件本身。该区域将页面直接映射到内核的文件系统缓冲区页面[它们已经统一了很长时间]。因此,不需要像对read(2)所做的那样,从内核文件系统缓冲区页复制到应用程序页。

当您执行malloc/read时,您仍然有上面的页面,但是,现在malloc'ed区域在分页/交换磁盘上有一个后备存储区。因此,页面缓冲区的数量是mmap的两倍。正如我提到的,当读取完成时,数据必须复制到区域中。

而且,在性能方面,进行大量读取是次优的。建议的大小在块中约为64 KB[依赖于文件系统]。

换句话说,当这个大的预执行发生时,应用程序正在等待[并且什么也不做]。对于60 GB的文件,启动时间是显而易见的。

如果您的文件确实足够大,那么您甚至会耗尽分页磁盘上的空间(即malloc返回NULL)。

对于mmap,不存在此类问题。当您映射一个文件时,您可以立即开始使用它。它将直接从该地区的后备存储(再次是文件系统中的文件)按需“出错”。而且,如果您有1个TB文件,mmap可以很好地处理这个问题。

在实践中,使用read,我看到在应用程序转移到文件的不同部分或完全不同的文件之后,用于FS缓冲区的内存量仍然很高。事实上,我曾经看到过一个I/O密集型应用程序使用如此多的缓冲区,以至于导致无关的[空闲]进程的页面被盗并刷新到分页磁盘。当我停止I/O应用程序时,firefox花了几分钟的时间才把自己分页回来并再次响应。

我对常规读取与MMAP做了一些广泛的基准测试。从中,mmap可以提高某些应用程序的速度。

请看我的答案:以最有效的方式逐行阅读*平台特性*

 类似资料:
  • 问题内容: 我想使用(为了提高速度)编写非结构化格式的日志文件(一次一行)。最好的程序是什么?我是否要打开空白文件至1页大小(写空字符串以调整文件大小?),然后-在mmaped区域已满时重复? 我通常使用在一个时间写固定大小的结构,通常只有一个页面,但是这是(从0.5的任何地方- 10 Gb)的写入日志文件使用mmap,但不知道什么是最好的做法,一旦第一mmaped区域充满- ,调整文件大小和下一

  • 问题内容: 我知道以前有一些关于文件读取,二进制数据处理和整数转换的问题,所以我来这里询问我有一段代码,我认为这花费了太多时间。所读取的文件是多通道数据样本记录(短整数),具有插入的数据间隔(因此有嵌套语句)。代码如下: 使用此代码,使用具有2Mb RAM的双核,每兆字节读取2.2秒,并且我的文件通常具有20+ Mb,这会带来一些非常令人讨厌的延迟(特别是考虑到另一个我试图镜像加载文件的基准共享软

  • 我正在开发一个应用程序(为Android和iPhone)。实际上,在我的应用程序中,我必须在后台下载很多视频(使用后台服务,IntentService),以及我有一个屏幕显示下载的进度(使用一个活动,有UI显示下载进度)。但我不知道为什么下载速度比iPhone中的相同应用程序的下载速度要慢得多。 此外,每次下载视频后,我会在数据库中标记该视频为下载。所有视频都会发生这种情况。 数据库调用是Andr

  • 本文向大家介绍如何提高javascript加载速度,包括了如何提高javascript加载速度的使用技巧和注意事项,需要的朋友参考一下 方法如下: 1、将所有<script>标签放在尽可能接近<body>标签底部的位置,以保证页面在脚本运行之前完成解析尽量减少对整个页面下载的影响 2、限制页面的<script>总数也可以改善性能。每当页面解析碰到一个<script>标签时, 紧接着有一段时间用于代

  • 问题内容: 我正在尝试使用以下内容使用Swift操场读取文本文件 但是,这将失败且没有错误。似乎第一行阻止了Playground在下面输出任何内容 问题答案: 这对我有用。我更改的唯一一件事是明确显示了文件名(在您的示例中已暗示)-也许您在“文件”变量的屏幕外定义中有错字? 更新Swift 4.2 正如@raistlin指出的那样,现在 或者,更简洁地说:

  • 问题内容: 我需要一个非常大的mmap文件的无拷贝调整大小,同时仍然允许并发访问读取器线程。 一种简单的方法是在同一进程中在同一文件上使用两个MAP_SHARED映射(增长文件,然后创建第二个映射,其中包括增长的区域),然后在所有可访问该文件的读取器完成操作后取消映射旧映射。但是,我很好奇下面的方案是否可行,如果可行,是否有任何好处。 使用MAP_PRIVATE映射文件 对多个线程进行只读访问 要