内存映射文件访问速度很慢

memory mapped file access is very slow

我正在 Linux 具有 976 GB 内存的机器上写入一个 930GB 的文件(预分配)。

该应用程序是用 C++ 编写的,我正在使用 Boost Interprocess 对文件进行内存映射。在开始代码之前,我设置了堆栈大小:

ulimit -s unlimited

一周前写的很快,今天运行慢了。我不认为代码已更改,但我可能不小心更改了我的环境中的某些内容(它是一个 AWS 实例)。

应用程序 ("write_data") 似乎没有使用所有可用内存。 "top" 显示:

Tasks: 559 total,   1 running, 558 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni, 98.5%id,  1.5%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  1007321952k total, 149232000k used, 858089952k free,   286496k buffers
Swap:        0k total,        0k used,        0k free, 142275392k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                  
  4904 root      20   0 2708m  37m  27m S  1.0  0.0   1:47.00 dockerd                                                                  
 56931 my_user   20   0  930g  29g  29g D  1.0  3.1  12:38.95 write_data                                                          
 57179 root      20   0     0    0    0 D  1.0  0.0   0:25.55 kworker/u257:1                                                           
 57512 my_user   20   0 15752 2664 1944 R  1.0  0.0   0:00.06 top

我认为驻留大小 (RES) 应该包括内存映射数据,所以它不应该 > 930 GB(文件大小)吗?

有人可以建议诊断问题的方法吗?

内存映射通常不会急切填充。如果某些其他程序将文件强制放入页面缓存,您会从一开始就看到良好的性能,否则您会在文件被分页时看到性能不佳。

假设您有足够的 RAM 将整个文件保存在内存中,您可能想提示 OS 它应该预取文件,减少页面错误触发的小读取次数,用更大的文件代替批量读取。 The posix_madvise API 可用于提供此提示,通过将 POSIX_MADV_WILLNEED 作为 advice 传递,表明它应该预取整个文件。