加快文件I / O:mmap()与read()
我有一个Linux应用程序,并行读取150-200文件(4-10GB)。 每个文件依次以小的,可变大小的块来读取,通常每个小于2K。
我目前需要保持超过200MB / s的读取速率,这些文件组合在一起。 磁盘处理这很好。 预计需求超过1 GB / s(目前超出磁盘范围)。
我们已经实现了两个不同的读取系统,都使用posix_advise
:首先是一个mmap
ed读取,我们映射整个数据集和按需阅读。 第二个是基于read()
/ seek()
的系统。
这两个工作正常,但只适用于温和的情况下, read()
方法更好地pipe理我们的整体文件caching,可以很好地处理100 GB的文件,但速度有限, mmap
可以预caching数据,使持续数据速率超过200MB / s容易维护,但不能处理大的总数据集大小。
所以我的问题来到这些:
答:可以将read()
types的文件I / O进一步优化,超出了Linux上的posix_advise
调用,或者调整了磁盘调度程序,VMM和posix_advise调用是否如我们所期望的那样好?
B:有没有系统的方法让mmap更好地处理非常大的映射数据?
Mmap-vs-reading-blocks与我正在工作的是类似的问题,并为此问题提供了一个很好的起点,以及mmap-vs-read中的讨论。
回读什么? 这个数据的最终目的是什么?
既然听起来你完全是IO界限, mmap
和read
应该没什么区别。 有趣的部分在于如何将数据传送到接收器。
假设你把这些数据放在一个pipe道中,我build议你把每个文件的内容全部转储到pipe道中。 要使用零拷贝完成此操作,请尝试splice
系统调用。 您也可以尝试手动复制文件,或者将cat
的实例或其他可以缓冲大量当前文件的工具作为标准input,并将pipe道作为标准输出。
if (pid = fork()) { waitpid(pid, ...); } else { dup2(dest, 1); dup2(source, 0); execlp("cat", "cat"); }
Update0
如果您的处理与文件无关,并且不需要随机访问,则需要使用上述选项创buildpipe道。 您的处理步骤应接受来自stdin或pipe道的数据。
要回答你更具体的问题:
答:可以将read()types的文件I / O进一步优化,超出了Linux上的posix_advise调用,或者调整了磁盘调度程序,VMM和posix_advise调用是否如我们所期望的那样好?
就如何告诉内核从用户空间执行什么操作一样好。 其余的由你决定:缓冲,线程等,但这是危险的,可能是非生产性的猜测工作。 我只是把文件拼接成一个pipe道。
B:有没有系统的方法让mmap更好地处理非常大的映射数据?
是。 下面的选项可能会给你带来令人惊叹的性能优势(并且可能使mmap值得使用超过阅读和testing):
-
MAP_HUGETLB
使用“巨大页面”分配映射。这将减less内核中的分页开销,如果您将映射千兆字节大小的文件,这将是非常好的。
-
MAP_NORESERVE
不保留此映射的交换空间。 当交换空间被保留时,可以保证可以修改映射。 当交换空间未被保留时,如果没有可用的物理内存,则可以在写入时获得SIGSEGV。如果实际上没有足够的物理内存+交换整个映射,这将防止内存不足,同时保持简单的实现。
-
MAP_POPULATE
填充(缺省)页面表的映射。 对于文件映射,这会导致文件上的预读。 以后访问映射不会被页面错误阻塞。这可能会给你提供足够的硬件资源,如果预取是有序的,而且是懒惰的。 我怀疑这个标志是多余的,VFS默认情况下可能会更好。
也许使用readahead系统调用可能会有帮助,如果你的程序可以预先预测它想要读取的文件片段(但这只是一个猜测,我可能是错的)。
而且我认为你应该调整你的应用程序,甚至是你的algorithm来读取大于几千字节的数据块。 不能超过半兆字节呢?
这里的问题似乎并不是使用哪个api。 使用mmap()或read()并不重要,光盘仍然需要查找指定的点并读取数据(尽pipeos有助于优化访问)。
如果读取非常小的块(几个字节),mmap()与read()相比具有优势,因为您没有为每个块调用os,从而变得非常缓慢。
我还build议像Basile那样连续读取2kb以上,这样光盘就不用经常去寻找了。
- 为什么在Windows 7上检测到FileSystemWatcher属性更改但不是Windows 8?
- 像YouTube一样的GUID
- StreamWriter.Flush()和StreamWriter.Close()有什么区别?
- Visual C#2010 Express中的unit testing?
- UnobservedTaskException被抛出,但它由TaskScheduler.UnobservedTaskException处理程序和一个continuation OnlyOnFaulted处理程序处理
- 静态variables是线程安全的吗? C#
- IHttpHandler与IHttpModule
- WebAPI 2中的DefaultInlineConstraintResolver错误
- Linq中的Enumerable.Zip扩展方法有什么用?