2015-10-28 44 views
1

我注意到在执行这样的命令后,我越来越有系统的响应速度(桌面GUI)的主要问题:读取文件,但提示内核不要缓存其内容?

cat file_larger_than_ram.bin | ./simple-process

我的理论是,这将导致Linux内核丢弃的文件,将会举行缓存到目前为止在RAM的未使用部分。同时,进程需要访问他们所处理的数据,因此在执行上述命令后,他们必须重新加载文件。鉴于我只打算使用file_larger_than_ram.bin一次,有没有办法暗示内核不缓存文件?我听说,我可以用fadvise对于这一点,但我不知道是什么给说fadvise64(2)

POSIX_FADV_DONTNEED尝试释放缓存与指定区域相关联的网页。例如,这是很有用的,而 正在流式传输大文件。程序可能会定期请求内核 释放已使用的缓存数据,以便更有用的缓存页面不会被丢弃。

应用fdadvise (input_desc, 0, 0, POSIX_FADV_DONTNEED);实际上表现得如我所料,并在此解决问题?

+0

检查它的任何问题?从描述看来它应该起作用 –

+0

测试所有替代方法需要很长时间,所以我想我会问,以防有人知道答案。它看起来像“dd”可能在这里很有用 - 我建议增加到'cat':https://lists.gnu.org/archive/html/coreutils/2015-10/msg00111.html,并发现它已被拒绝一次。 – d33tah

+1

你见过这个http://unix.stackexchange.com/questions/36907/drop-a-specific-file-from-the-linux-filesystem-cache? –

回答

2

鉴于我只打算使用file_larger_than_ram.bin一次,有没有办法提示内核不缓存文件?

据我所知,这可能与O_DIRECT标志到open系统调用。但是该标志带有其他限制(例如文件偏移和用户空间内存缓冲区对齐),这可能会导致问题。他们在测试中并没有给我带来任何问题,但文档表明这种行为是特定于设备/文件系统的。因此,我将我的代码更改为使用fadvise()

(此外,我观察到一些性能违规行为(该read()/write()是太快了),这表明,即使与O_DIRECT一些数据有时都拿到缓存。情况因人而异。)

我听说,我可以用但我不确定[...]

我也不清楚,所以我检查了内核源代码。与POSIX_FADV_DONTNEED调用fadvise()的效果是从缓存中删除相应的数据。我还没有看到任何暗示该标志是粘性并适用于所有文件操作。 (这就是为什么我检查了源代码:我知道Linux通过高速缓存执行I/O 总是O_DIRECT是替代方案,粘滞POSIX_FADV_DONTNEED不符合范例。)

换句话说,读你在释放缓存需要:

  • 保持文件之前read()

  • read()

    偏移的轨道上的范围内调用fadvise(POSIX_FADV_DONTNEED)你刚读过的数据。

  • 为了获得最佳效果,您必须读取页对齐块中的数据。 I/O缓存是基于页面的,并且fadvise()将指定的数据范围映射到页面列表中。错位会导致额外的损失(并损害性能),但其他方面无害。

为了写它是稍微复杂一些:我观察到,fadvise(POSIX_FADV_DONTNEED)没有如果write()后立即叫效应。必须呼叫fsync()/fdatasync()强制写入数据,从而取消锁定缓存条目,然后才调用fadvise(POSIX_FADV_DONTNEED)以释放它们。

P.S.就我所了解的内核代码而言,由@AlexHoppus链接的dd的技巧应该可行。例如cat file; dd if=file of=/dev/null iflag=nocache - cat调用会将文件放入缓存中,dd会从缓存中读取它,然后将其从缓存中丢弃。 fadvise(POSIX_FADV_DONTNEED)在全局缓存上运行,因此,读取数据时谁/何时无关紧要,无论如何都会丢弃它们。