我怎样才能获得预读字节?

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

或者,我可以使用内存映射文件。 在这种情况下,问题就变成了找出页面是否交换到磁盘。 这可以在任何普通的操作系统中完成吗?

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

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

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

mincore()返回一个向量,该向量指出调用进程的虚拟内存页面是否驻留在内核(RAM)中,如果引用,则不会导致磁盘访问(页面错误)。 内核返回关于从地址addr开始的页面的驻留信息,并且继续length字节。

这里当然有一个竞争条件mincore()可以告诉你一个页面是常驻的,但是在访问它之前可能会被换出。 C'est la vie

你是从一个错误的推定开始的。 至少在Linux上,操作系统将试图找出程序的访问模式。 如果您按顺序读取文件,则内核将按顺序预取。 如果你经常跳过这个文件,内核可能会首先被混淆,但是它会停止预取。

所以,如果你实际上顺序访问你的文件,你知道什么可能prefetched:下一个数据块。 如果你正在随机寻找,那么附近可能没有任何东西被预取。

尝试以不同的方式来处理这个问题。 在调用read()来获取所需的信息之前,调用fadvise()让操作系统知道你想要它开始加载什么。

我也很好奇,知道你正在使用什么样的应用程序,可以正常运行,只是偶然地处理文件缓存中的数据。 我觉得我们可以找到一个很好的方式来解决您的需求,如果你发布了一些信息。

它当然不能在Windows上完成。 在Windows上,预读行为取决于操作系统,即使它可以告诉你预读了多少,它也不会对你有任何好处,因为只要你发现了,内存页面是用于缓存可能已被回收一些其他用途。

同样的事情决定一个页面是否是常驻的。 一旦你发现答案可能会改变,当其他线程需要内存的东西。

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

我可以使用什么API来查找操作系统缓存中的内容?

对于任何posix系统,当然没有标准的方法来做这件事,而且我也没有意识到任何特定于Linux的非标准方式。 唯一可以确定(几乎)可以肯定的是文件系统将读取多倍的页面大小,通常是4kB。 所以,如果你的读数很小,你可以很有可能知道(尽管不是很确定)周围页面的数据在内存中。

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

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

最后,我第二@ Karmastan的建议:解释你想要实现的更广泛的目标。 有可能有办法做到这一点,但你所建议的不是这样。