2010-04-28 33 views
1

從磁盤讀取的操作系統不僅僅是程序實際請求的內容,因爲程序將來可能需要附近的信息。在我的應用程序中,當我從磁盤獲取項目時,我想顯示元素周圍的信息間隔。在我要求和展示的信息量和速度之間存在權衡。但是,由於操作系統已經讀取了比我要求的更多的內容,所以在內存中訪問這些字節是免費的。我可以使用哪些API來查找操作系統緩存中的內容?如何獲得預讀字節?

或者,我可以使用內存映射文件。在這種情況下,問題可以歸結爲找出頁面是否交換到磁盤。這可以在任何普通的操作系統中完成嗎?

編輯:相關論文http://www.azulsystems.com/events/mspc_2008/2008_MSPC.pdf

+0

從磁盤中提取的項目有多大?獨立於預讀,文件系統將以塊大小(通常爲4KB)爲單位從磁盤讀取數據。因此,如果你的項目,比如100個字節,也許你可以簡化你的問題,以顯示項目在同一個塊---你可以計算,而不訴諸花哨的接口。 – 2010-05-02 20:54:51

+0

我想知道操作系統讀取的靜態最小值,但不是它爲特定操作實際讀取的字節數。 – 2010-05-03 13:00:07

回答

5

你確實可以使用你的第二種方法,至少在Linux上。 mmap()該文件,然後使用mincore()函數確定哪些頁面駐留。從手冊頁:

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

mincore()返回一個向量 表示調用 進程的虛擬內存的頁面是否駐留 核心(RAM),因此不會造成 接盤(頁面錯誤)如果 被引用。內核返回 關於從地址addr, 開始的 頁的駐留信息,並且繼續爲length字節。

當然這裏有一個競賽條件 - mincore()可以告訴你,一個頁面是常駐的,但它可能會在你訪問它之前被換出。 C'est la vie

+0

[vmtouch](http://hoytech.com/vmtouch/vmtouch.c)從命令行(* nix)打印文件緩存統計信息 – 2011-06-16 17:34:58

1

它肯定不能在Windows上進行。在Windows上,預讀行爲取決於操作系統,即使它可以告訴你預讀了多少,它也不會對你有任何益處,因爲一旦找到了,內存頁面就是用於緩存可能已被回收用於其他用途。

確定頁面是否駐留也是同樣的事情。只要你發現答案可能會改變,當其他線程需要內存的東西。

如果你真的想在Windows上做這種事情,你可以關閉緩衝並自己管理緩衝區。這是最快的IO路徑,但它也是最複雜的 - 你必須非常小心,並且通常操作系統仍然可以做得更好。

+0

關於確定頁面是否是常駐頁面和實際閱讀頁面之間的競爭條件的觀點很好。然而,即使沒有像我想做的那樣做任何事情,你仍然處於頁面驅逐的擺佈之中。一個普通的fread調用可以返回並且在我使用它之前內存頁消失。 – 2010-04-28 19:43:28

+0

正確 - 儘管這種可能性不大 - 除非您受到嚴重的內存壓力,否則操作系統不太可能將最近使用的專用頁面分頁,因爲它必須將它們寫入磁盤。高速緩存頁面或內存映射文件頁面已存在於磁盤上,因此操作系統丟失的代價要低得多。無論哪種方式,它不是看起來的勝利 - 你應該儘可能多的閱讀,並希望儘可能的自由。 – Stewart 2010-04-28 19:53:04

2

你剛從一個錯誤的推定出發。至少在Linux上,操作系統會試圖找出程序的訪問模式。如果您按順序讀取文件,則內核將按順序預取。如果你跳過這個文件,內核可能會很困惑,但是它會停止預取。

所以如果你真的順序訪問你的文件,你知道什麼可能prefetched:下一個數據塊。如果你正在隨機尋找,那麼附近可能沒有任何東西被預取。

試着用不同的方法來解決這個問題。之前調用read(),讓你需要,叫fadvise()讓OS知道你它開始加載什麼,我也很想知道你是什麼樣的應用的信息..

使用它可以正確運行,只需對偶然發生在文件緩存中的數據進行操作即可。如果您發佈了更多信息,我覺得我們可以找到解決您需求的好方法。

+0

我很抱歉讓人失望,但我沒有具體的使用。它發生在我閱讀www.cs.sunysb.edu/~bender/pub/BenderHu-TODS07.pdf和其他有關緩存遺忘的文章。 – 2010-04-29 02:04:15

1

我可以使用哪些API來找出操作系統緩存中的內容?

對於任何posix系統,當然沒有標準的方法來做到這一點,我不知道任何特定於Linux的非標準方式。你唯一能夠確定(幾乎)可以肯定的是文件系統將讀取多倍的頁面大小,通常是4kB。所以,如果你的讀數很小,你可以很有可能知道(儘管不是很確定)周圍頁面中的數據在內存中。

我想,你可以做一些技巧性的事情,比如計時多久才能完成讀取系統。如果速度很快,那就是100微秒或更少,這可能是緩存命中。一旦達到一毫秒左右,這可能是一個緩存未命中。當然,這實際上對你沒有什麼幫助,而且非常脆弱。

請注意,一旦文件系統已將數據複製到用戶緩衝區,可自由立即丟棄從磁盤中保存數據的緩衝區。它可能不會馬上這樣做,但你無法確定。

最後,我第二@卡爾瑪斯坦的建議:解釋你試圖達到的更廣泛的目標。有可能有辦法做到這一點,但你建議的不是這樣。