fadvise vs madvise?我可以一起使用吗?

Ami*_*aki 4 c linux mmap file

我在一个巨大的文件中随机读取数据(每个读取<页面大小)(太大而不适合内存).

我通常设置MADV_DONTNEED,但看看文档+信息似乎我需要FADV_NOREUSE.

我真的没有得到如何madvise()fadvise()一起工作.他们是同义词吗?如果我喜欢其中一个是否重要?它们可以一起使用吗?它们是不同的内核子系统吗?是FADV_NOREUSE什么我正在寻找获得最佳性能?

nir*_*iry 6

madvise()和posix_fadvise()不是同义词.madvise()告诉内核(给出建议)如何处理现有内存区域,而fadvise()告诉内核如何处理文件数据的缓存(或未来缓存).

例如,如果您使用mmap()匿名区域,则应使用madvise()来提示内核不要换出(MADV_RANDOM)或仅在访问后换出.(MADV_SEQUENTIAL)

如果您使用mmap()文件或文件的一部分,您可以使用madvise()或fadvise()来提示内核为您预读(MADV_WILLNEED)或释放该缓存(MADV_DONTNEED)或在访问后释放(除上述之外,还有POSIX_FADV_NOREUSE,fadvise()).

如果使用file而不将数据映射到进程内存(不使用mmap()),则应仅使用fadvise().madvise()没有任何意义.

就内核子系统而言,在linux中,它是同一个子系统,只是不同的方式来引用内存页面和文件缓存.请注意,这些只是提示,当内存处于可怕状态时,尽管有提示,内核可能会决定换出或重用缓存数据.只有mlock()和mlockall()才能防止这种情况发生.

在您的情况下,不提供任何提示可能会有所帮助,特别是如果某些页面被读取比其他页面更多,因为内核将确定哪些页面"热"并将尝试保留在内存中.


Ser*_* L. -2

如果您只是从文件中读取,那么您实际上不需要。分页守护进程将自动释放与非脏或共享文件支持的映射关联的 RAM 页。如果您继续调用,madvise/MADV_DONTNEED那么您是在专门指示内核执行此操作。如果您在不久的将来偶然再次访问同一页面,可能会导致性能影响。

fadvise仅当您使用read/lseek. 对于mmapped 页面来说,它没有效果。

  • 这就是理论。不幸的是,Linux 有一个故意破坏的“MADV_DONTNEED”实现,它将“丢弃修改过的页面”,而不仅仅是非脏页面。`fadvise` 在缓冲区高速缓存上工作,这要归功于统一的虚拟内存系统_确实_影响映射文件。我不确定“FADV_DONTNEED”是否也被破坏了(从未尝试过),但人们可以希望。如果它能正常工作,那么它将非常有用。 (4认同)