2011-01-28 106 views
1

我有這樣的代碼讀取二進制數據的64MB到內存:優化文件的讀取和寫入

 

#define SIZE 8192 
char* readFromFile(FILE* fp) 
{ 
    char* memBlk = new char[SIZE*SIZE]; 
    fread(memBlk, 1, SIZE*SIZE, fp); 
    return memBlk; 
} 

int main() 
{ 
    FILE* fp = fopen("/some_path/file.bin", "rb+"); 
    char* read_data = readFromFile(fp); 
    // do something on read data 
    // EDIT: It is a matrix, so I would be reading row-wise. 
    delete[] memBlk; 
    fclose(fp); 
} 

當我單獨使用此代碼,運行時間小於1秒。 但是,當我把完全相同的代碼(僅用於基準測試)時,在我們的一個應用程序中,運行時間爲146秒。該應用程序相當龐大,最高可達5G內存使用量。

其中一些可以通過當前的內存使用情況,緩存未命中和其他因素來解釋,但相差146倍聽起來對我來說不合理。

有人可以解釋這一點嗎?

內存映射可能會提高性能。任何其他建議也是受歡迎的。

謝謝。

機信息: Linux my_mach 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

編輯:

謝謝您的回答,但是,我錯過了這樣的事實,實際上在這裏我插的地方是本身被稱爲25倍,因此它不完全是146的因素。

不管怎樣,答案是有幫助的,謝謝你的時間。

+2

爲什麼使用動態分配的內存來存儲固定大小的緩衝區? – 2011-01-28 13:16:53

+1

@Blagovest:你並不是建議在*堆棧*中存儲64MB的數據,對嗎? – thkala 2011-01-28 13:18:56

+0

「// ......做些什麼?」呢? – 2011-01-28 13:19:17

回答

3

它看起來像您的代碼所需的額外內存會導致應用程序中出現抖動,該應用程序可能已經在極限運行。

如果你想「有所作爲」與文件,您可以:

  • 處理文件列塊

  • 使用mmap()或操作系統上的一些類似的內存映射技術來地圖如果您需要更復雜的訪問,則將文件存入內存

    mmap ing使用緩衝區緩存作爲後備存儲將頁面內容分頁到交換空間的文件本身insead中。使用mmap通常是訪問文件的最簡單方法。雖然不是完全可移植的(它可以製成便攜式在OS'es的UNIX組的一致好評例如,所有的BSD,Linux,Solaris和MacOSX的和)

你並沒有說明具體的訪問模式「做什麼」會因此很難推薦一些特定的技術

1

該過程可能沒有64MB的免費商店在一個連續的塊中隨時可用。你可以嘗試將64MB緩衝區分成一些小塊,比如64K或256K大小的塊,然後看看它是否有助於提高性能?

3

5G是一個巨大的內存量,你確定你有這麼多的物理內存。如果不是146倍差異的原因可能是由於交換到磁盤嘗試釋放內存。

你也應該看看在64位機器上使用64位操作系統。