Gözlenen etki esasen doğrudur, ancak yöntem en az iki nedenden dolayı kusurludur.
Çeşitli dosya boyutları değil çeşitli dosya boyutları test edilir. Bunun nedeni, dd'ye aynı iki dosyadan okuma ve yazma talimatı vermesidir, sadece bs=
(okuma ve yazma parçaları) parametresi değişir.
/ Dev / zero çıktı hızı, istenen bayt miktarını ileteceği için okuma talebinin boyutundan (veya tamponundan) etkilenecektir. Bu giriş kayıtları tarafından bildirilir.
1 baytta görünen yavaşlama, dosyayı oluşturmak için içeriği oluşturmak ve okumaktan daha fazla zaman almasından kaynaklanırken, 10K'daki hız artışında, dosya oluşturma işlemi genel süreye hakim olmaktan çıkar Deneme. O andan itibaren hız düşüşü, test dosyasının bulunduğu ortamın seri çekim (sıralı) hızına tabidir.
Çeşitli dosya boyutlarının göreceli hızını ölçmek için aşağıdakiler gibi belirli bir veri miktarını ayırmanız gerekir:
100MB to 10 files
10MB to 100 files,
1MB to 100 files,
500KB to 204 files,
64K to 1600 files
1K to 102400 files.
Medyanın blok / sektör boyutu ve tek bir dosya için dosya sistemi (blok boyutu) minimum ayırma boyutu gibi diğer faktörler de ortaya çıkar.
Talaşın yorumuna verilen tepkiler.
Dd komutundaki "bs" blok büyüklüğü içindir ve sayıyla birleştirildiğinde, G / Ç oranını hesaplamak için uygun bir aktarım boyutu belirtilir
Bu ikisi ile uygun ve kesin bir boyut seçilebilir, ancak G / Ç oranı çok düşük olacaktır bs=
. Bildiklerime göre (man dd, GNU Coreutils), dd parametresi bs=BYTES
"her seferinde BYTES baytına oku ve yaz" ile açıklanmaktadır. Bana göre bu sesler:
int bs // read upto bs bytes in each read operation.
byte[] buffer
while ( bs = file.readIntobufferAndReturnBytesRead(buffer) ) {
... use data in buffer
}
Başka bir deyişle, birçok küçük okuma ve yazma, bir büyükten daha uzun sürecektir. Bunun sahte bir ifade olduğunu düşünüyorsanız, önce bir 5L kepçeyi çay kaşığı ile doldurduğunuz bir deneyi yapabilir ve bardaklarla aynı görevi tamamlamak için gereken zamanı karşılaştırabilirsiniz. İç işleyişine daha aşina olursanız dd
, lütfen neden bs=
"blok boyutu" olduğuna ve kodda bunun ne anlama geldiğine dair kanıtlarınızı sunun.
İşte ikinci ifadem neden anlamlıdır:
Sabit trial.sh:
MB10="
10MB 1
1MB 10
512KB 20
256KB 40
128KB 80
64KB 160
32KB 320
16KB 640
4KB 2560
1KB 10240
512 20480
64 163840
1 10485760
"
BLOCKS100="
10MB 100
1MB 100
512KB 100
256KB 100
128KB 100
64KB 100
32KB 100
16KB 100
4KB 100
1KB 100
512 100
256 100
128 100
64 100
32 100
16 100
4 100
1 100
"
function trial {
BS=(`echo -e "$1" | awk '{print $1}'`)
CO=(`echo -e "$1" | awk '{print $2}'`)
printf "%-8s %-18s %7s %12s %8s\n" bs count data time speed
for ((i=0;i<${#BS[@]};i++ )); do
printf "%-8s %-18s" "bs=${BS[i]}" "count=${CO[i]}"
dd if=/dev/zero of=/dev/null bs=${BS[i]} count=${CO[i]} \
|& awk '/bytes/ { printf "%10s %-12s %8s\n", $3" "$4, $6, $8""$9 }'
done
echo
}
trial "$BLOCKS100"
trial "$MB10"
.
$ sh trial.sh
bs count data time speed
bs=10MB count=100 (1.0 GB) 0.781882 1.3GB/s
bs=1MB count=100 (100 MB) 0.0625649 1.6GB/s
bs=512KB count=100 (51 MB) 0.0193581 2.6GB/s
bs=256KB count=100 (26 MB) 0.00990991 2.6GB/s
bs=128KB count=100 (13 MB) 0.00517942 2.5GB/s
bs=64KB count=100 (6.4 MB) 0.00299067 2.1GB/s
bs=32KB count=100 (3.2 MB) 0.00166215 1.9GB/s
bs=16KB count=100 (1.6 MB) 0.00111013 1.4GB/s
bs=4KB count=100 (400 kB) 0.000552862 724MB/s
bs=1KB count=100 (100 kB) 0.000385104 260MB/s
bs=512 count=100 (51 kB) 0.000357936 143MB/s
bs=256 count=100 (26 kB) 0.000509282 50.3MB/s
bs=128 count=100 (13 kB) 0.000419117 30.5MB/s
bs=64 count=100 (6.4 kB) 0.00035179 18.2MB/s
bs=32 count=100 (3.2 kB) 0.000352209 9.1MB/s
bs=16 count=100 (1.6 kB) 0.000341594 4.7MB/s
bs=4 count=100 (400 B) 0.000336425 1.2MB/s
bs=1 count=100 (100 B) 0.000345085 290kB/s
bs count data time speed
bs=10MB count=1 (10 MB) 0.0177581 563MB/s 566MB/s 567MB/s
bs=1MB count=10 (10 MB) 0.00759677 1.3GB/s 1.3GB/s 1.2GB/s
bs=512KB count=20 (10 MB) 0.00545376 1.9GB/s 1.9GB/s 1.8GB/s
bs=256KB count=40 (10 MB) 0.00416945 2.5GB/s 2.4GB/s 2.4GB/s
bs=128KB count=80 (10 MB) 0.00396747 2.6GB/s 2.5GB/s 2.6GB/s
bs=64KB count=160 (10 MB) 0.00446215 2.3GB/s 2.5GB/s 2.5GB/s
bs=32KB count=320 (10 MB) 0.00451118 2.3GB/s 2.4GB/s 2.4GB/s
bs=16KB count=640 (10 MB) 0.003922 2.6GB/s 2.5GB/s 2.5GB/s
bs=4KB count=2560 (10 MB) 0.00613164 1.7GB/s 1.6GB/s 1.7GB/s
bs=1KB count=10240 (10 MB) 0.0154327 664MB/s 655MB/s 626MB/s
bs=512 count=20480 (10 MB) 0.0279125 376MB/s 348MB/s 314MB/s
bs=64 count=163840 (10 MB) 0.212944 49.2MB/s 50.5MB/s 52.5MB/s
bs=1 count=10485760 (10 MB) 16.0154 655kB/s 652kB/s 640kB/s
İkinci kusurun ilgili kısmı, veri boyutunun sabit olduğu zamandır (10 MB). Çok küçük parçalar için hız belli ki daha yavaş. "Drop" u bs = 10MB’de nasıl açıklayacağımdan emin değilim, ancak dd’nin büyük parçalar için arabelleğe alma işleminden nasıl kaynaklandığını tahmin edebilirim.
Bunun altına girmek zorunda kaldım (varsayımlarıma meydan okuyan talaş sayesinde) ...
Tampon boyutu == bs hakkındaki varsayımım yanlıştır, ancak bs parametresi, boyutu tamponu basan bir gg ile gösterildiği gibi boyutu etkilediği için tamamen yanlış değildir. Bu, ikinci kusurumun sayfa boyutunun 4K olduğu sistemlerde <8K dosyaları ile ilgili olmadığı anlamına gelir:
$ ./dd if=/dev/zero of=/dev/null bs=1 count=1
OUTPUT_BLOCK_SLOP: 4095
MALLOC INPUT_BLOCK_SLOP: 8195, ibuf: 8196
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.000572 s, 1.7 kB/s
$ ./dd if=/dev/zero of=/dev/null bs=1805 count=1
OUTPUT_BLOCK_SLOP: 4095
MALLOC INPUT_BLOCK_SLOP: 8195, ibuf: 10000
1+0 records in
1+0 records out
1805 bytes (1.8 kB) copied, 0.000450266 s, 4.0 MB/s
(coreutils 8.20'den dd.c)
line:text
21: #define SWAB_ALIGN_OFFSET 2
97: #define INPUT_BLOCK_SLOP (2 * SWAB_ALIGN_OFFSET + 2 * page_size - 1)
98: #define OUTPUT_BLOCK_SLOP (page_size - 1)
1872: real_buf = malloc (input_blocksize + INPUT_BLOCK_SLOP); // ibuf
1889: real_obuf = malloc (output_blocksize + OUTPUT_BLOCK_SLOP); // obuf
// if conversion is on, othervise obuf=ibuf
2187: page_size = getpagesize ();
adam 3 memcpy
void *memcpy(void *dest, const void *src, size_t n);
The memcpy() function copies n bytes from memory area src to memory area
dest. The memory areas must not overlap. Use memmove(3) if the memory
areas do overlap.