2010-10-29 41 views
1

我有一種情況,需要使用大(幾百MB)數據結構的數字(15-30)。他們不會同時適應所有的記憶。更糟糕的是,對它們進行操作的算法可以在所有這些結構上工作,即不是第一種,然後是其他等等。我需要儘可能快地完成這些。內存映射文件性能 - 使用大型數據集時的內存管理

所以我想我會分配內存在磁盤上,基本上是直接二進制表示的數據,當它被加載到內存中的文件,並使用內存映射文件來訪問數據。我使用例如50兆的mmap'views'(一次將50 MB的文件加載到內存中),所以當我有15個數據集時,我的進程使用750 MB的內存來存儲數據。最初(測試)確定的是,當我獲得更多數據時,我會以一定的速度調整50 mb。

然而,這種啓發式算法現在是硬編碼的(我知道我將測試的數據集的大小)。 「在野外」,我的軟件需要能夠確定分配的「正確」內存量,以最大限度地提高性能。我可以說'我將以500 MB的內存使用爲目標',然後將500除以數據結構的數量以達到mmap視圖的大小。我發現當試圖設置這個'目標內存使用率'太高時,虛擬內存管理器磁盤抖動將(幾乎)鎖定機器並使其不可用,直到處理完成。這是在我的「生產」解決方案中要避免的。

所以我的問題,都有些不同的方法的問題:

  • 什麼是單個進程的「最好」的目標尺寸是多少?我是否應該儘量使我擁有的2GB(假設32位Win XP及更高版本,現在不支持/ 3GB)或儘量縮小我的進程以便我的軟件不會佔用機器?當我的計算機上有2個Visual Studio,Outlook和Firefox打開時,那些使用1/2 GB的虛擬內存很容易 - 如果我讓我的軟件使用2 GB虛擬內存,交換將嚴重降低計算機的速度。但是,如何我確定'最好'的過程大小。

  • 如何在使用內存映射文件時保持機器的性能?我的應用程序對數據進行了相當簡單的數字操作,這基本上意味着它可以快速地將數百兆字節的數據壓縮,導致整個內存映射文件(幾千兆字節)被加載到內存中,並再次非常快速地重新換出(想想蒙特卡羅風格模擬)。

  • 有沒有機會不使用內存映射文件,只使用fseek/fgets會比使用內存映射文件更快或更少侵入?

  • 我可以閱讀的任何文章,論文或書籍?無論是「食譜」風格的解決方案還是基本概念。

謝謝。

+0

規格爲64位操作系統,問題解決。 – 2010-10-29 14:49:17

+0

是的,希望我能在幾年內做到這一點...... – Roel 2010-10-29 14:55:18

+1

@Hans - 今天64位和32位的普及率是多少?這似乎是限制性的,也許在10年內這是合理的。 – 2010-10-29 14:55:47

回答

1

在我看來,您可以設置一些預定義的「太慢」的閾值,並使用計算機的掛鐘來進行即時更改。

保守地低開始。如果這低於您的「太慢」的閾值,那麼爲下一個文件增加一點點大小。反覆做這個。當你超過門檻時,反覆緩慢退回尺寸。

1

我覺得這是嘗試地址窗口擴展的好去處:http://msdn.microsoft.com/en-us/library/aa366527(v=VS.85).aspx

它將允許通過提供一個滑動窗口來使用超過4GB的內存。缺點是並非所有版本的Windows都有。

+0

這將要求我的用戶使用6或8或10 GB RAM的機器,我希望能夠滿足這些要求(比如上面提到的64位機器),但對於我的目標市場來說這是不可行的。我需要管理軟件中的內存問題,我不能把硬件扔在它上面。 – Roel 2010-10-29 15:33:44

0

將內存映射文件的大小修改爲總系統內存的一定百分比,可能最好設置爲最好。

請記住,當您訪問單個字節時,操作系統將有效加載整個內存頁面,這可能發生在後臺,但只有在順序數據訪問趨於接近時纔會很快。

因此,您應該儘量保持順序訪問您的數據,儘可能靠近內存/文件。您也可以看看預加載策略在實際需要數據之前推測性地訪問您的數據。這些與爲內存高速緩存效率進行優化時需要的考慮事項相同。

如果順序數據訪問分散在您的文件中,您最好使用fseek和fread來訪問數據,因爲這樣可以更好地控制什麼時候將數據寫入內存。

還請記住,沒有硬性規定。優化有時可能是違反直覺的,所以嘗試一大堆不同的東西,看看哪個平臺最適合需要操作。

1

我可能不會使用這個應用程序的內存映射文件。當你有一個大的虛擬地址空間時(至少相對於你正在處理的數據的大小),內存映射文件效果最好。您映射整個文件,並讓操作系統決定哪些片段仍然駐留。但是,如果您反覆映射和取消映射文件的各個段(而不是整個文件),您可能最終也會通過fseekfread讀取塊 - 但請注意,你不要想這樣讀取個別數據(即做一個大的讀取,而不是很多小的讀取)。

手動分割內存映射文件可能獲勝的一種方式是如果您有稀疏讀取:如果您只會觸摸,說給定文件的10%。在這種情況下,內存映射意味着操作系統將只讀取那些被觸摸的頁面,而顯式讀取則會載入整個文件。

呵呵,我肯定會不是花時間試圖控制我的資源消耗。操作系統會比你做得更好,因爲它知道所有競爭過程。

+0

再次閱讀您的問題後,我會建議您考慮如何交錯原始文件,或使用map-reduce類型設計(nb:map-reduce不*需要多臺機器)拆分計算。 – Anon 2010-10-29 17:40:06