2009-11-04 57 views
9

我需要將數據寫入驅動器。我有兩個選擇:將原始數據寫入驅動器或寫入文件會更快嗎?

  1. 寫入原始的扇區(_寫(手柄,p緩衝器,大小);)
  2. 寫入到一個文件中(FWRITE(p緩衝器,大小,計數,PFILE);)

哪種方式更快?

我期望原始扇區寫入函數_write更高效。但是,我的測試結果失敗了! fwrite速度更快。 _花費時間更長。

我粘貼了我的代碼片段;也許我的代碼是錯誤的。你能幫我嗎?無論哪種方式,是我好,但我覺得生寫比較好,因爲它似乎在驅動器中的數據至少是加密....

#define SSD_SECTOR_SIZE 512 
int g_pSddDevHandle = _open("\\\\.\\G:",_O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    _write(g_pSddDevHandle,szMemZero,SSD_SECTOR_SIZE); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
FILE * file = fopen("f:\\test.tmp","a+"); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    fwrite(szMemZero,SSD_SECTOR_SIZE,1,file); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
+4

寫的原始數據是不加密的話 - 它只是混淆用戶... – bdonlan

+3

+1分析。 (儘管這個問題在我頭頂) – GManNickG

+0

要bdonlan:我只是希望它看起來就像是encrypted..invisible用戶 –

回答

6

在_write()的情況下,SSD_SECTOR_SIZE的值很重要。在fwrite的情況下,每個寫入的大小實際上是BUFSIZ。要獲得更好的比較,請確保底層緩衝區大小相同。

但是,這可能只是差異的一部分。

在fwrite的情況下,您正在測量將數據存入內存的速度。您沒有將stdio緩衝區刷新到操作系統,並且您沒有要求操作系統將緩衝區刷新到物理存儲。爲了更準確地比較,您應該在停止定時器之前調用fflush()。

如果您確實在意將數據導入磁盤而不是將數據存入操作系統緩衝區,則應確保在停止定時器之前調用fsync()/ FlushFileBuffers()。

其他明顯的差異:

  • 驅動器是不同的。我不知道有多不同。

  • 寫入設備的語義與寫入文件系統的語義不同;文件系統被允許延遲寫入以提高性能,直到明確告知不要(例如用標準句柄,調用FlushFileBuffers());直接寫入設備不一定會以這種方式進行優化。在另一方面,該文件系統必須做額外的I/O管理元數據(塊分配,目錄項等)

我懷疑你看到一個不同的政策如何快速事情實際上進入磁盤。原始磁盤性能可能非常快,但您需要大量寫入操作,最好是多個併發的未完成操作。您也可以在打開手柄時使用正確的選項避免緩衝區複製。

+0

結果是fwrite比_write快10倍... SSD_SECTOR_SIZE是512 –

+0

如果在每次調用fwrite之後調用fflush(),性能應該會顯現大致相等。但是,正如janm所提到的,這裏還涉及其他變量,例如OS緩存。 –

+1

如果你真的關心性能,我會嘗試更大的寫入,一次說1MB。或者甚至只需要一次調用write函數,然後調用flush函數即可。現代硬盤不寫行業,他們寫軌道。爲了獲得準確的比較,你應該刷新緩衝區。 – janm

18

可能是因爲直接寫入沒有緩衝。當您撥打fwrite時,您正在進行緩衝寫入,在大多數情況下,寫入速度會更快。本質上,每個FILE*處理程序都有一個內部緩衝區,當它變滿時,它會定期刷新到磁盤,這意味着您最終會減少系統調用,因爲您只能以較大的塊寫入磁盤。

換句話說,在第一次循環中,實際上是在每次迭代過程中將SSD_SECTOR_SIZE字節寫入磁盤。在你的第二個循環中,你不是。您只將SSD_SECTOR_SIZE個字節寫入內存緩衝區,這取決於緩衝區的大小,只會在每第N次迭代時刷新一次。

相關問題