【发布时间】:2021-01-29 17:49:16
【问题描述】:
在开发和测试时,我有一个非常大的文件需要加载到内存中。每次运行程序大约需要 20 秒。
有没有办法将文件保存在内存中,这样就不需要每次都加载了?
【问题讨论】:
-
只是发表想法,您可以通过另一个程序将其保存在共享内存中并以这种方式访问。
在开发和测试时,我有一个非常大的文件需要加载到内存中。每次运行程序大约需要 20 秒。
有没有办法将文件保存在内存中,这样就不需要每次都加载了?
【问题讨论】:
这取决于您所说的“已加载”。
如果您是指将数据从存储传输到内存,这或多或少是您的操作系统的 IO 缓存应该做的事情,假设您有足够的备用内存并且您没有使用绕过该缓存的方法。
在linux上它被称为页面缓存,你可以通过fincore检查文件是否在缓存中。或者您可以通过echo 3 > /proc/sys/vm/drop_caches 模拟冷缓存,这将删除其内容(需要root)。
如果您的意思是将字节从操作系统的缓存移动到您的应用程序中,那么只要您使用足够大的块大小进行读取调用或使用 mmap,就不会花费太多时间。后者是一把双刃剑,使用不当实际上会导致减速。
如果您的意思是将字节解码为某些特定于应用程序的逻辑,那么这不是 IO,而是反序列化。
【讨论】:
mmap + posix_madvise 与标志POSIX_MADV_WILLNEED 通常通过告诉操作系统您需要处理整个文件来消除此类问题,因此它(通常,规范不保证,因为这只是建议)主动填充页面,而不是按需填充对页面错误的响应。其他建议可用于“内存文件太大”,具体取决于它们的使用方式(例如,SEQUENTIAL,当它全部读取一次并被丢弃时)。
mmap() 总是会涉及创建物理到虚拟的映射,这既昂贵又严重的性能瓶颈。如果这些映射只使用一次,或者由于内存压力而被分页或换出而必须重新映射,则可能会导致mmap() 比简单地使用read() 慢。对于mmap(),只读取一次文件然后丢弃它是最糟糕的用例。