Dd

dd 延遲寫入 CF

  • January 26, 2015

我有一個舊的 64MB CF 卡,我在筆記型電腦(核心 2.6.38)中使用它和 CardBus 適配器。如果我向這張 CF 卡寫入一個 64MB 的圖像,那麼寫入速度超過 200MB/s:

T42 ~ # fdisk -lu

Disk /dev/sda: 40.0 GB, 40007761920 bytes
255 heads, 63 sectors/track, 4864 cylinders, total 78140160 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00043afc

  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    73947135    36972544   83  Linux
/dev/sda2        73949182    78139391     2095105    5  Extended
/dev/sda5        73949184    78139391     2095104   82  Linux swap / Solaris

Disk /dev/sdb: 64 MB, 64225280 bytes
8 heads, 32 sectors/track, 490 cylinders, total 125440 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

  Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *          32      125300       62634+   4  FAT16 <32M
Partition 1 has different physical/logical endings:
    phys=(488, 7, 32) logical=(489, 3, 21)
T42 ~ # mount | grep -i sdb
T42 ~ # time dd if=64MB of=/dev/sdb bs=10M
6+1 records in
6+1 records out
64225280 bytes (64 MB) copied, 0.320419 s, 200 MB/s

real    0m0.624s
user    0m0.000s
sys 0m0.304s
T42 ~ #

對於 10 年前的 CF 卡,在 0.32 秒內 64MB 顯然是不現實的,如果我在dd if=64MB of=/dev/sdb bs=10M完成後立即從筆記型電腦中取出卡,我會看到很多輸出<timestamp> end_request: I/O error, dev sdb, sector <sector number>錯誤。dmesg什麼可能導致這種行為?

塊設備寫入由核心緩衝。當文件系統被掛載時,這一點清晰可見(當你解除安裝時,緩衝區必須被刷新,導致有時在umount返回之前有很長的延遲)。隨著可用 RAM 越來越大,這種延遲似乎越來越嚴重。您甚至可以在核心初始化數據傳輸之前立即寫入半 GB。在您看到傳輸完成後,核心可能會在幾分鐘內透明地寫入設備。

出於多種原因,此功能非常好。它允許對設備的讀寫響應更快,數據也可以透明讀取在寫入之後,甚至在實際物理寫入完成之前從緩衝區中提取。對於長期掛載的硬碟,核心會在有時間的時候安排寫入,同時讓設備從使用者的角度更快地響應。特別是對於磁性硬碟驅動器,按順序寫入大塊也比在整個驅動器的多個位置寫入小塊要快:塊可以在推送到物理設備之前進行排序和分組(儘管硬碟驅動器也會進行一些緩沖和數據排序在硬體內部)。簡而言之,您不會注意到設備的速度很慢,並且您也不會注意到初始延遲(如果網路安裝的驅動器或硬碟驅動器必須從休眠中啟動)。

對於直接訪問塊設備,緩衝有點不幸,因為您不呼叫umount並且您不會真正注意到傳輸何時完成。無論如何****你都應該打電話。sync

引用自:https://unix.stackexchange.com/questions/181089