【问题标题】:fadvise vs madvise? can I use both together?fadvise vs madvise?我可以同时使用吗?
【发布时间】:2013-11-22 14:58:13
【问题描述】:

我在一个巨大的文件中随机读取数据(每次读取

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

我真的不明白madvise()fadvise() 是如何协同工作的。它们是同义词吗?我喜欢一个或另一个有关系吗?它们可以一起使用吗?它们是不同的内核子系统吗? FADV_NOREUSE 是我想要获得最佳性能的东西吗?

【问题讨论】:

标签: c linux file mmap


【解决方案1】:

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

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

如果您 mmap() 一个文件或文件的一部分,您可以使用 madvise() 或 fadvise() 来提示内核为您预读 (MADV_WILLNEED) 或释放该缓存 (MADV_DONTNEED) 或释放访问后(POSIX_FADV_NOREUSE,仅 fadvise())。

如果您使用文件而不将数据映射到进程内存(不使用 mmap()),则应仅使用 fadvise()。 madvise() 没有意义。

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

在您的情况下,不提供任何提示可能会有所帮助,尤其是在某些页面被读取的次数多于其他页面时,因为内核会找出哪些页面是“热的”并尝试保留在内存中。

【讨论】:

    【解决方案2】:

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

    fadvise 仅在您使用read/lseek 访问文件时才有用。对于mmapped 页面,它无效。

    【讨论】:

    • 理论就是这样。不幸的是,Linux 有一个故意破坏的MADV_DONTNEED 实现,它将丢弃修改过的页面,而不仅仅是非脏页面。 fadvise 适用于缓冲区缓存,这要归功于统一的虚拟内存系统确实影响映射文件。我不确定FADV_DONTNEED 是否也坏了(从未尝试过),但可以希望。如果它可以正常工作,那么它将非常有用。
    • “如果你只是从一个文件中读取,那么你实际上也不需要。” -> 你确定吗?我正在阅读 LKML,当您从要复制的文件中读取块时,它正在谈论 FADV_NOREUSE。
    • @AmirTaaki 分页守护进程可能更擅长决定从 RAM 中清除哪些页面。而且由于您不会弄脏它们 - 它有很多可供选择。
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2015-05-19
    • 2019-05-21
    • 2021-09-05
    • 2014-04-08
    • 2020-06-23
    相关资源
    最近更新 更多