2013-10-14 100 views
1

我必須計算一個巨大的nxn矩陣(n> 100000)並以某種方式將它存儲在內存中以備後用。單個元素的計算非常昂貴(幾千次觸發器和內存訪問),所以我無法實時計算它。不過,我只需要計算一次,不需要稍後修改它。我也不能認爲我有足夠的交換空間在系統上。這就是爲什麼我決定創建一個緩存文件,並使用mmap把它映射到內存:使用mmap時性能下降

int createCacheFile(std::size_t filesize, std::string const& filename){ 
    //create empty file 
    int fileDescriptor = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); 
    //stretch to desired size 
    lseek(fileDescriptor, filesize-1, SEEK_SET); 
    return fileDescriptor; 
} 

//... 
std::size_t n = 100000; 
std::size_t fileSize = n*n*sizeof(float); 
int fileDescriptor = createCacheFile(filesize,"matrix.cache"); 
float* memory = (float*) mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0); 

//and now fill it... 

我想比較性能和嘗試了小的N = 10000和比較的malloc,MMAP與MAP_ANONYMOUS和上面的實現。對於這個n矩陣完全適合RAM。雖然malloc和MAP_ANONYMOUS給出了非常相似的結果,但在計算矩陣時受到文件支持時,我會得到大約10倍的懲罰。看起來程序經常被內核停止,以便它可以安全地將內容寫入文件。我嘗試在我已經計算的矩陣部分使用msync和mprotect來解決這個問題,以便爲內核提供一個提示,即它可以編寫這些部分而不必停止程序,但沒有任何幫助。

有沒有辦法解決這個問題?

+3

您需要[調整虛擬機](http://www.cyberciti.biz/faq/linux-kernel-tuning-virtual-memory-subsystem/)不會阻止您的進程,即使有很多髒頁需要寫入的內存。 –

+0

會在RAM中創建文件解決問題? –

+0

@DavidSchwartz太棒了!我不知道這些設置。謝謝!我現在將dirty_background_ratio更改爲5,將dirty_ratio更改爲80.除了使用SSD加速寫作之外,我還可以做些什麼?是否有助於告訴msync它可以將第一個k頁作爲連續塊寫入?或者內核會自行解決問題? – user2878433

回答

0

您也可以使用系統調用madvise(2)來通知內核關於不太有用的頁面(可能與MADV_SEQUENTIALMADV_DONTNEED ...)。也許posix_fadvise(2)系統調用可能對文件段有幫助。最終readahead(2)(在另一個線程中,因爲它阻塞)也可能有幫助。

和文件可能會坐在一個快速的文件系統,也許是tmpfs一個....

也許換一個快速的磁盤(SSD)上也可能是有用的。 swapon(2)系統調用(和swapon命令)。