【发布时间】:2018-02-17 22:47:18
【问题描述】:
对于我的神经网络训练项目,我有一个非常大的输入数据文件。文件格式是二进制的,它由大量固定大小的记录组成。该文件目前约为 13GB,但将来可能会变得更大;出于这个问题的目的,我们假设它太大而不能一次将所有这些都保存在我的计算机的 RAM 中。
今天的问题涉及我编写的一个小实用程序(用 C++,虽然我认为语言的选择在这里并不重要,因为在任何语言中都可能遇到相同的问题),旨在读取大文件和输出一个类似的大文件——输出文件包含与输入文件相同的数据,除了将记录打乱成随机顺序。
为此,我将mmap()输入文件放入内存,然后生成一个从1到N的整数列表(其中N是输入文件中的记录数),随机打乱该列表的顺序,然后遍历列表,将 mmap 内存区域中的第 n 条记录写入输出文件。
就目前而言,这一切都正常工作;问题是它不能很好地扩展;也就是说,随着输入文件的大小变大,进行此转换所需的时间增加得比 O(N) 快。它已经到了成为我工作流程瓶颈的地步。我怀疑问题是 I/O 系统(对于 MacOS/X 10.13.4,使用我的 Mac Pro 垃圾桶的内部 SSD,以防这很重要)针对顺序读取进行了优化,并跳转到完全随机的位置就缓存/预读/其他 I/O 优化而言,输入文件几乎是最坏的情况。 (我想在旋转磁盘上,由于磁头寻道延迟,它的性能会更差,但幸运的是,我至少在这里使用 SSD)
所以我的问题是,我可以使用任何聪明的替代策略或优化来使这个文件随机化过程更有效——随着我的输入文件大小的增加可以更好地扩展?
【问题讨论】:
-
数据库?
-
对于这种用途,您可能不需要完全统一的排列选择,因此您可以使用适合内存的块。
-
我能看到的最佳解决方案是让使用随机文件的进程从非随机文件中进行挑选 - 换句话说,永远不要创建随机文件。
-
@NeilButterworth 这不只是解决问题吗?如果我这样做了,我认为使用该文件的进程会运行得很慢,原因与当前进程运行缓慢的原因相同......
-
如果文件在 SSD 上,即使它针对顺序读取进行了优化,读取的数据越多,它也不会变得越来越慢。您是否尝试过不使用
mmap()? Just usepread()另外,这里的一些想法可能会有所帮助:stackoverflow.com/questions/2299402/…
标签: c++ io mmap large-files random-access