My friends, my life, my style - James S.F. Hsieh

12/30/2009

JPG, PNG, BMP 速度大車拼

由於工作的關係我得嘗試去分析在相似的軟硬體環境, 小型的影像檔案到底哪個格式的 access 速度比較快呢? 嚴格說這個問題在現代的多工作業系統下是不容易有個穩定的答案, 但是我們還是值得去找到個趨勢來改進我們程式的效能.

首先我們先定義小檔案有多小, 我取了一個以 80x80 的 24bit BMP 檔案做為基準, 該檔案的大小是 19,254 Bytes (磁碟大小 20,480 Bytes), 相對應的 PNG 為 17,533 Bytes (磁碟大小 20,480 Bytes), JPG 為12,532 Bytes (磁碟大小 16,384 Bytes). 我所選擇的 codec 為 Windows Vista 內建的 WIC decoder.

實驗的設計必須考慮作業系統對檔案快取造成的影響以及硬碟檔案的分佈與離散成度, 所以我做了以下的設計:
  1. 在實驗前先對目的磁碟做 defragment 來減少斷裂與離散的問題
  2. 利用程式對三種格式產生 0000~9999 為編號的 10K 個檔案 
  3. 每次從 10K 檔案中隨機抽 1K 個檔案做為實驗之用降低快取的影響
  4. 每次實驗後都重新開機, 開機後等待系統進入穩態以確保快取的影響降到最低
以下是兩個實驗內容:

實驗一:
對 10K 檔案中隨機抽 1K 個檔案, 使用 WIC 載入記憶體並且 decode 其四次實驗結果如下:
  • PNG: 81, 86, 109, 110 平均 96.5 files/sec 120%
  • JPG: 77, 102, 89, 93 平均 90.25 files/sec 112%
  • BMP: 71, 75, 85, 89 平均 80 files/sec 100%
該實驗的目的在於知道混合 CPU bound 與 I/O bound 的情況下, 不同格式在 WIC codec 的速度

實驗二:
一個檔案已經事先載入到記憶體中, 然後使用 WIC 對相同記憶體 decode 10K 次其結果如下:
  • JPG:  1788 files/sec 159%
  • BMP: 1118 files/sec 100%
  • PNG:  963 files/sec  86%
該實驗的目的在於知道如果排除 I/O bound 的問題, 不同格式在 WIC codec 下速度

其實有只要有 I/O 因素的狀況下變異數都很大, 結果令人訝異的是 PNG 在第一個實驗有較好的表現, 但第二個實驗不考慮 I/O bound 的狀況下卻是最差的, 我能想到的解釋就是 JPG 在 decode 需要花費比較多的 seek time, 但是以磁碟機這種 block based device 來說這些檔案最多才佔 4 個 sectors 而且 JPG 檔案還比較小所以只佔 3 個, 所以 seek 動作應該是不太會發生在一次的 decode 中畢竟硬體不會一次只讀一個 sector.

所以這兩個實驗的結果還是沒有一個合裡的解釋, 誰能告訴我為什麼呢?

從實驗來看可以知道實驗一是個 I/O bound 遠高於 CPU bound 的問題, 所以加速的關鍵會再如何更好的降低 I/O 的影響, 所以我設計下個實驗:

實驗三:
以三種格式做隨機存取來分析哪種方式的 I/O 效率最好,
  1. 使用原來的方法做為基準, 一個目錄有 10K 個檔案
  2. 將 10K 個檔案合併成一個很大的檔案, 純粹將多個檔案 "黏" 在一起
  3. 將 10K 個檔案合併成一個很大的檔案, 使用 COM Structured Storage 來儲存
實驗的結果如下以 PNG 檔案為例
  • Big chunk file: 309 240 351 平均 300 files/sec 238% 
  • 10K files: 104 139 135 平均 126 files/sec 100%
  • Structured Storage file: 100 72 72 平均 81.3 files/sec 64%
結果變異數還是不小, 不過可以看出一個趨勢就是 Big chunk file 比分散的檔案快而且快很多, 而 COM Structured Storage 是最慢的.

實驗四:
對 Structured Storage 檔案中隨機抽 1K 個檔案, 使用 WIC 載入記憶體並且 decode 其三次實驗結果如下:
  • JPG: 90, 92, 91, 平均 91 files/sec 133%
  • BMP: 68, 68, 69, 平均 68.3 files/sec 100%
  • PNG: 65, 66, 66, 平均 65.6 files/sec 97%
結果的變異數並不大, 且實驗中CPU 使用率很高, 以雙核心且程式使用一個 thread 的情況下, CPU 使用率約 50~54%. 但是實驗一的情況下 CPU使用率相對低很多. 其實 Structured Storage 在大檔案的狀況下效能真的不好但是功能確還蠻迷人, 如果單純用在諸如 Word 這類軟體的 serialize 上的確非常方便, 相關的經驗還可參考 Performance of structured storage files.