代码之家  ›  专栏  ›  技术社区  ›  Bruno Martinez

如何获取预读字节?

  •  1
  • Bruno Martinez  · 技术社区  · 15 年前

    操作系统从磁盘读取的信息比程序实际请求的要多,因为程序将来可能需要附近的信息。在我的应用程序中,当我从磁盘获取一个项目时,我想显示元素周围的信息间隔。在我请求和展示的信息量和速度之间有一个权衡。但是,由于操作系统已经读取了比我请求的更多的内容,所以访问内存中已经存在的这些字节是免费的。我可以使用什么API来查找OS缓存中的内容?

    或者,我可以使用内存映射文件。在这种情况下,问题会减少到查明页面是否被交换到磁盘上。这可以在任何常见的操作系统中完成吗?

    编辑:相关论文 http://www.azulsystems.com/events/mspc_2008/2008_MSPC.pdf

    4 回复  |  直到 15 年前
        1
  •  5
  •   caf    15 年前

    您确实可以使用第二种方法,至少在Linux上是这样。 mmap() 文件,然后使用 mincore() 函数确定哪些页是驻留的。从手册页:

    int mincore(void *addr, size_t length, unsigned char *vec);

    mincore()。 返回一个向量 指示调用页 进程的虚拟内存是驻留的 在核心(RAM)中,因此不会导致 磁盘访问(页面错误)如果 参考。内核返回 居住信息 从地址开始的页面 addr , 继续 length 字节。

    当然这里有比赛条件- mincore()。 可以告诉您某个页面是驻留的,但在您访问它之前,它可能会被换出。 最新生活

        2
  •  2
  •   Karmastan    15 年前

    你从错误的假设开始。至少在Linux上,操作系统会尝试找出程序的访问模式。如果按顺序读取文件,内核将按顺序预取。如果您经常跳过该文件,内核可能会在一开始就被混淆,但随后它将停止预取。

    所以如果你真的 按顺序访问文件,您知道可能预取了什么:下一个数据块。如果你是随机寻找,可能附近没有其他东西是预取的。

    试着用不同的方法来处理这个问题。在调用read()获取信息之前, 需要 ,呼叫 fadvise() 让操作系统知道你 希望 开始加载……

    我还想知道您使用的应用程序是哪种类型的,只需对碰巧在文件缓存中的数据进行操作,就可以正确运行。我觉得如果你发布更多信息,我们可以找到一个很好的方法来满足你的需求。

        3
  •  1
  •   Stewart    15 年前

    当然不能在窗户上做。在Windows上,预读行为取决于操作系统,即使它能告诉你它预读了多少,也不会对你有任何好处,因为一旦你发现了,用于缓存的内存中页面可能已经被回收用于其他用途。

    同样的事情也适用于确定一个页面是否是常驻的。一旦你发现答案可能会改变,当其他线程需要内存来处理其他事情时。

    如果你真的想在Windows上做一些事情,你可以关闭缓冲区并自己管理缓冲区。这是最快的IO路径,但也是最复杂的路径——您必须非常小心,而且通常操作系统仍然可以做得更好。

        4
  •  1
  •   Dale Hagglund    15 年前

    我可以使用什么API来查找OS缓存中的内容?

    当然,对于任何POSIX系统都没有标准的方法来实现这一点,我也不知道Linux特有的任何非标准方法。你唯一能确定(几乎)的是文件系统将以页面大小的倍数读取,通常是4KB。因此,如果您的读取量很小,您很有可能(尽管不确定)知道周围页面中的数据在内存中。

    我想,你可以做一些棘手的事情,比如定时阅读系统需要多长时间才能完成。如果速度很快,也就是100秒或更少,那么可能是缓存命中。一旦达到一毫秒左右,可能是缓存丢失。当然,这实际上对你没什么帮助,而且很脆弱。

    请注意,一旦文件系统将数据复制到用户缓冲区,就可以立即丢弃保存来自磁盘的数据的缓冲区。它可能不会马上这样做,但你不能确定。

    最后,我附和了@kamastan的建议:解释一下你试图实现的更广泛的目标。可能有办法,但你建议的不是。

    推荐文章