2011-11-09 34 views
1

聲明:這可能是一個研究問題,因爲我找不到我在找什麼,而且它很具體。用於管理共享mmapped文件的庫或工具

問題:我有一個自定義搜索應用程序,需要在每個介於0.01MB到10.0MB之間的100K和10M文件之間讀取。每個文件都包含一個可以通過mmap直接加載爲數組的數組。我正在尋找一種解決方案,在需要之前將文件預取到RAM中,如果系統內存已滿,則彈出已經處理完畢的文件。

我知道這聽起來很像操作系統內存管理和類似memcached的組合。我實際上在尋找的是類似於memcached的東西,它不返回字符串或鍵的值,而是所選數組的開始地址。此外,(這是一個不同的主題)我希望能夠管理共享內存,使得CPU內核與RAM之間的距離在NUMA機器上最短。

我的問題是:「這樣的工具/庫是否已經存在?」

回答

1

你的問題是有關this one

我不知道你需要找到一個圖書館。你只需要瞭解如何有效地使用系統調用。

我相信readahead系統調用可以幫到你。

+0

您的評論正指向我正確的方向。這個問題和[其他](http://stackoverflow.com/questions/8056984/speeding-up-file-io-mmap-vs-read)之間的主要區別是在這裏文件的數量很高,但每個文件相對較小。在另一種情況下,情況正好相反。我真正需要做的是非阻塞I/O(至少從消費者的角度來看),並讓內核不要將那些尚未被消費者讀取的文件分頁出去。給定足夠的內存,我只是將所有的數組保存在內存中。 –

+0

如果您可以預測下一秒將需要什麼文件(或其中的一部分),那麼使用'readahead'系統調用(可能在單獨的線程中)應該會有所幫助。 –

+0

我有點擔心readahead是阻塞呼叫。此外,這個問題的主要動機是展望未來,因爲對於一個CPU內核來說,I/O模式看起來很重要,我想擴展到許多內核而不會讓它們捱餓。另一個(單獨的問題)是大多數I/O分析器針對具有一個線程的進程進行編程,而且對於多線程進程來說更糟糕。 –

0

事實上,你有很多很多文件(也許它們太多了)。我希望你的文件系統足夠好,或者它們在許多目錄中。擁有數百萬個文件可能會成爲一個問題,如果沒有適當調整(但我不會在這方面有所幫助)。

我不知道你的應用程序是誰寫的&讀取很多文件。也許你可以考慮切換到快速DBMSPostGresQLMySQL,或者你可以使用GDBM

+0

過去我們嘗試過使用MySQL,但是它比從Linux文件系統讀取文件的時間大約要長十倍。另外,該應用程序更像下面描述的搜索引擎。讀取速度是重要的,寫入是週期性完成的,不會覆蓋以前的任何數據,並且可能會很慢。 –

+0

GDBM也可能有用。我相信它可能比MySQL更快,甚至可能比擁有數百萬個文件的文件系統更快。 –

0

我曾經爲搜索引擎類應用程序做過這件事。它使用了一個LRU鏈,它也可以通過file-id和內存地址IIRC進行尋址(通過散列表)。在每次訪問時,將項目重新定位到LRU鏈的頭部。當內存變得緊張(mmap 可能失敗...)時,LRU鏈的尾部未被映射。

該方案的缺陷是程序可能會在頁面錯誤時被阻止。而且由於它是單線程的,所以真的被封鎖。將此更改爲多線程體系結構將涉及通過鎖和信號量來保護哈希和LRU結構。

之後,我意識到我在做雙緩衝:操作系統本身有一個完美的LRU磁盤緩衝機制,這可能比我更聰明。只需在每個請求上打開()ing或mmap()ing每個文件,只有一個sytemcall消失,並且(對於最近的活動),速度與緩衝層一樣快,甚至更快。數據庫管理系統:使用數據庫管理系統是一個乾淨的設計,但你只有最小的3個系統調用的開銷,只是爲了獲得第一個數據塊。它肯定會(總是)塊。但它適合於多線程設計,並且可以讓您擺脫鎖和緩衝區管理的困擾。

+0

我一直在想這些。我們可能只需購買一臺具有足夠內存的專用機器來保存整個數據集。在我的手中,使用C++ fstream,read()或mmap沒有區別。只要操作系統認爲有足夠的文件緩衝空間,讀取速度就會很快。 –