dd 延遲寫入 CF
我有一個舊的 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