我使用 dd 來測量寫入效能,並觀察到一些奇怪的現象:寫入 /data/emzed2 比寫入 /data 更快。這是我衡量性能的方法:
$ dd if=/dev/0of=/data/emzed2/testfileBS=32
^C4921834+0 筆記錄
4921834+0 記錄複製了 157498688 位元組 (157 MB),2,87329 秒,54.8 MB/秒
$ dd if=/dev/0of=/數據/測試文件BS=32
^C2487991+0 筆記錄
2487991+0 記錄複製了 79615712 位元組 (80 MB),2,6501 秒,30,0 MB/秒
這兩個資料夾位於 SSD 磁碟機的相同分割區上。我使用Ubuntu 14.04並重複了幾次實驗,結果相似。
知道發生了什麼事嗎?
答案1
看來你受到了 ext4 優化的影響。其中一些描述於Ext4 磁碟佈局文件.
每次成長文件時(例如使用 dd),都會為新資料分配一些位置。最終,檔案可能會被碎片化,即資料可能會分散在磁碟上的多個區塊中。碎片是眾所周知的速度緩慢的根源(讀取和寫入時),因此檔案系統實作通常會嘗試避免它。與 SSD 相比,旋轉磁碟(磁頭需要移動到連續的區塊)的碎片化成本更高,但大多數檔案系統實作都使用 SSD 的旋轉磁碟最佳化策略。
上述文件中所述的第三、第四和第五個「技巧」的組合可能解釋為什麼在您的情況下寫入子目錄更快。
第五個技巧是將磁碟區分割成 128MB 的區塊組。 [...] 當在根目錄中建立目錄時,inode 分配器會掃描區塊組並將該目錄放入它可以找到的負載最輕的區塊組中。
結果,emzed2
可能是在 128MB 的空區塊中建立的。
第四個技巧是,如果可行,目錄中的所有 inode 都放置在與目錄相同的區塊組中。
因此,/data/testfile
是在(可能負載較重的)根塊組中建立的,而 是在(可能是空的)區塊組/data/emzed2/testfile
中建立的。emzed2
第三個技巧[…]是它嘗試將檔案的資料塊與其索引節點保留在同一塊組中。
對於/data/emzed2/testfile
,檔案系統會先分配emzed2
塊組中的所有資料塊。如果這個區塊最初是空的,對於前 128MB,這意味著根本沒有碎片。對於/data/testfile
,檔案系統如果還沒有填充的話,會先填充根塊組,然後再尋找其他地方來儲存資料。
此外,您一次將檔案增長 32 個位元組。幸運的是,諸如 ext4 之類的檔案系統會分配比您請求的更多的資料(在 ext4 的情況下為 8kb 區塊),並嘗試延遲分配。您可能會看到類似的模式bs=8196
,但速度差異可能會隨著區塊大小的增加而減少。