2013-02-15 72 views
2

對於這個問題,我從文件加載一個大的三維體積到一個程序中,但通常只需要在三個平面(x,y,z)上進行查看。我目前正在使用Boost :: Interprocess :: File_Mapping來創建文件(32 GB)的映射並將其加載到具有24 GB RAM的系統中。當前方法使用單個Boost :: Interprocess :: Mapped_Region作爲文件。內存使用率快速接近99%。通過Boost的file_mapping和mapped_region最小化內存使用情況?

我是新來的內存映射文件I/O的世界,並想知道如何最好地分割文件,以減少內存使用量。創建縮小尺寸的區域(例如每個Z平面)是否會改善結果?我想盡可能少地使用記憶而不會造成不良影響。

我是以這種正確的方式去做的,還是有更直接的方法來執行此操作?

+0

你忘了指定平臺。 – Soonts 2013-02-16 04:19:57

+0

我沒有指定平臺,因爲這個概念被設計爲獨立的。我正在Windows上進行調試,但我應該包括在內。 – patemotter 2013-02-16 20:07:44

回答

1

在Windows上,它通常工作正常。我創建了一個測試應用(抱歉,我恨提振,因爲我覺得它的質量是appaling,我的示例使用ATL代替,但基本的Windows API都是一樣的):

HRESULT TestMain(LPCTSTR strFileName) 
{ 
    CAtlFile file; 
    HRESULT hr = file.Create(strFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); 
    if(FAILED(hr)) 
     return hr; 
    CAtlFileMapping<BYTE> mapping; 
    hr = mapping.MapFile(file); 
    if(FAILED(hr)) 
     return hr; 
    size_t sz = mapping.GetMappingSize(); 
    BYTE res = 0; 
    for(size_t i = 0; i < sz; i++) 
     res ^= mapping[ i ]; 

    printf("Read the complete file, %Iu bytes, the XOR is %.2X\n", sz, int(res)); 
    return S_OK; 
} 

當記者問到讀一個12GB的文件我的機器有8GB內存,我看到了你描述的效果(我的進程的資源監視器內存數據:提交25 MB,私有20 MB,工作集和共享的6.5 GB,這是我的空閒RAM的數量)。但是,互聯網上的多個來源表示,這些數字並不意味着什麼,也不會影響性能,因爲一旦有任何進程請求更多內存,就會丟棄未使用的物理頁面,而且這個過程非常便宜(除非您寫信給你的內存映射文件)。

或者,如果你真的不滿意這種行爲,你可以自己釋放未使用的部分,通過調用VirtualUnlock,如下所述:https://stackoverflow.com/a/1882478/126995

或者,你只能映射你需要的文件的部分。

但是你可以做的最好的 - 優化你的數據佈局。如果在您的數據文件中,您保留體素爲double voxels[x][y][z],請將它們存儲爲struct { double voxels[8][8][8] } blocks[x/8][y/8][z/8]。這樣,塊大小正好是4kb,這是一個頁面大小,如果你只需要訪問XZ飛機,你可以節省很多的I/O帶寬,數量級。只要不弄亂不對齊,即如果你的數據之前有一個頭,確保頭的大小是4kb * n,其中n是整數。

+1

感謝您的反饋。我知道佈局可以改善事情,但不知道我的結果是否應該發生。我可能會嘗試使用本地內存映射,因爲我也討厭使用Boost。 – patemotter 2013-02-16 20:14:47