2013-01-31 42 views
4


我有一個關於文件IO(C語言)及其性能問題的問題。文件IO性能C

我有一個應用程序,它執行大量的文件I/O(在其生命週期〜3-6小時,大約0.5-0.75TB,主要是文件輸出)。 此刻,我的應用程序sprintf()將所有內容都轉換爲char字符串,並在行尾write() s處轉換爲file_descriptor。我的字符串長度爲1024個字符,但可以在64到1024之間任意變化。無論如何。

的問題是:
會更有意義做出更大的字符字符串(比如,1MB?)和sprintf()一切都變成它做write()過嗎?或者,假設緩衝由write()負責處理,則直接跳過sprintf()完全且僅僅是write()更有意義?

東西我想過,但不確定是否會真正在性能方面一事無成:
如果我有,我存儲字符串,數字和字符串的各個部分,做的一個mem_copy結構結構呢?我猜測類似於二進制寫入?

我正試圖實現一種「緩衝」方法或任何可以最大限度提高性能的方法。 後者是我需要使用該文件進行進一步處理。 有什麼建議嗎?

編輯
我與printf(); + redirsprintf(); write();
我簡單地複製〜20GB到一個文件中的一些簡單的性能對比。

char string[1024]; 

for(i=0;i<(1<<20)*20;i++) 
    printf("%s",string); 

~/tmp/tests$ time ./printf.out > testing 
real 2m22.101s 
user 0m28.214s 
sys 0m29.294s 

,而不是:

char string14[256]; ...etc 
for(i=0;1<<(1<<20)*20;i++){ 
    sprintf(dst_string,"%s%s",dst_string, string14); 
    sprintf(dst_string,"%s%s",dst_string, string24); 
    sprintf(dst_string,"%s%s",dst_string, string34); 
    sprintf(dst_string,"%s%s",dst_string, string44); 
    write(fd, dst_string, 1024); 
} 

~/tmp/tests$ time ./write.out 

real 1m48.206s 
user 0m58.544s 
sys 0m41.079s 

其原因多的sprintf()s是模擬禁止複製>緩衝液,然後寫入緩衝器。 時間(真正的反正)並不像一些評論所暗示的那麼微不足道。當然這是一個簡單的例子,也許在計算方案+ IO也許它不會。

在printf例子中,我有點困惑,那些額外的時間去了哪裏?用戶+系統不加起來真的,他們不應該至少在球場?因爲整個1:30m失蹤。

此測試是否顯示任何結論? sprintf +寫入>只需打印+ redir?

無論如何,謝謝大家的意見。

+1

僅僅使用'printf'可能(幾乎可以肯定)比'sprintf'好,接着'write'。 –

+0

你不應該假設緩衝由'write'來處理。事實上,你應該假設'write'根本就沒有緩衝。 –

+0

但這會寫入標準輸出,我不得不重定向它,這是緩慢的,由終端限制,不是嗎?哦,我沒有fprintf可用。 – janjust

回答

5

當我在我的機器上進行了一些測試後,我的非現代硬件中出現了大約60MB/s的速度。這是3.6GB /分鐘或每小時216GB(因此3小時產生約640GB)。我希望在你的應用程序中花費的時間大多是「等待磁盤」,在這種情況下,它使用什麼IO方法完全沒有區別。

但是就像所有的性能問題一樣,它不是通過在互聯網上詢問,或者在書本上查找,或者任何其他方式找到的答案。必須在您關心的系統上進行測量。改變我的舊硬盤以獲得一些配置良好的RAID,並獲得更好的性能[如果它是正確的RAID系統 - 有些比單個磁盤慢,因爲其目的不是加速訪問,而是確保可靠性]。

您還可以進行一些比較: 1.將您的軟件輸出重定向到/ dev/null - 檢查現在運行您的代碼需要多長時間。如果它比寫文件時快10-100倍,那麼你知道現在寫的方式或其他方法根本沒有任何區別。 2.使用dd if=/dev/zero of=yourfile bs=4k count=largenumber(largenumber * 4KB =典型的文件大小)創建類似大小的文件 - 如果您的應用程序正在編寫多個文件,然後編寫一個腳本來編寫幾個不同的文件)。如果這比您的應用程序快得多,那麼通過改變您從應用程序輸出的方式可以獲得某些東西。

如果上述兩種情況中的任何一種都表明存在增益潛力,那麼編寫一些基準,這些基準會以您希望應用程序工作的相同方式產生大量輸出,並查看造成差別的原因。盡一切辦法回到這裏並提出問題。但我的猜測是,無論你如何處理輸出機制,你的應用程序不會運行得更快或更慢,因爲這完全取決於「磁盤寫入速度有多快」。

+0

在不仔細選擇緩衝區大小而不是使用標準設施的情況下調用'write'可能會導致I/O中斷,並且使用非常精心製作的'write'調用可能會將性能提高多達0.00001%(這會有所不同),所以它可能不正確的說它使「絕對沒有區別」。爲每個字節調用'write'保證會消除性能!但是,所有合理的方案將基本上相同。 –

+0

是的,我傾向於故意避免在我的答案中過於迂腐,因爲它實際上並沒有多大幫助。原來的問題已經提到,有1KB的塊,這應該沒問題 - 無論你用什麼方式在操作系統中都有緩衝。 –

+0

感謝評論傢伙,我想我必須對我的應用程序進行基準測試,以查看適當的緩衝區以調用write()。而且我看到@WilliamPursell來自何處,實際上即使由於IO而節省了少量的時間,我也不會看到任何改進。雖然謝謝! – janjust