dd 1 GB yerine 32 MB rasgele dosya üretiyor


50

1 GB rasgele bir dosya üretmek istedim, bu yüzden aşağıdaki komutu kullandım.

dd if=/dev/urandom of=output bs=1G count=1

Ancak bunun yerine bu komutu her başlattığımda 32 MB'lık bir dosya alıyorum:

<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s

Yanlış olan ne?

DÜZENLE:

Bu konudaki mükemmel cevaplar sayesinde 32 MB büyüklüğünde 32 GB okuyan ve 1 GB büyüklüğünde bir çözüm buldum:

dd if=/dev/urandom of=output bs=32M count=32

Doğrudan belleğe 1 GB okuyan ve daha sonra diske yazan başka bir çözüm verildi. Bu çözüm çok fazla hafıza alır, bu nedenle tercih edilmez:

dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock

3
IMHO Çok fazla geçerli kullanım durumu olduğunu sanmıyorum dd. Bana kalırsa doğru head, catya da rsynchemen hemen her zaman onun yerine. Ve sorunuz, alternatiflerin genellikle daha güvenli olmasının nedenlerinden biriyse.
Bakuriu

@Bakuriu - Ayrıca, sadece sıfır ile dolu bir dosya üretmek istiyorsanız (veya bunun içinde ne olduğu umrunda değil) kesik kullanın. Çok daha hızlı.
Konrad Gajewski

@KonradGajewski FYI kısaltması seyrek bir dosya oluşturmaya çalışıyor (eğer
önemliyse

5
@Bakuriu headbu görevi POSIX'de olmayan bir -cseçenek olmadan yapamaz . Bunu catçözebilecek hiçbir sürümü bilmiyorum . rsynctamamen standart olmayan bir yardımcı programdır. Orası burada değil; Adam sayfasında gezinirken, bu sorunu da nasıl çözebileceğini anlamıyorum.
Kaz

Teknik olarak, /dev/urandomPOSIX de değil ...
yerçekimi

Yanıtlar:


92

bsarabellek boyutu, dd tarafından yapılan tek bir okuma () çağrısının boyutunu ifade eder .

(Örneğin, her ikisi de bs=1M count=1ve bs=1k count=1k1 SGA dosyası neden olur, ancak ikinci 1024 parçalı halde yapacak Birinci versiyon, tek bir adımda yapacak.)

Düzenli dosyalar hemen hemen her tampon boyutunda okunabilir (arabellek RAM’a sığdığı sürece), ancak aygıtlar ve "sanal" dosyalar çoğu zaman bireysel aramalara çok yakın çalışırlar ve her biri için ne kadar veri üreteceklerini keyfi bir şekilde kısıtlarlar. okuma () çağrısı.

Çünkü /dev/urandombu sınır, urandom_read () ' da drivers / char / random.c içinde tanımlanmıştır :

#define ENTROPY_SHIFT 3

static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
    nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
    ...
}

Bu, işlev her çağrıldığında istenen boyutu 33554431 bayta sıkıştıracağı anlamına gelir.

Varsayılan olarak, diğer araçların aksine, dd istenenden daha az veri aldıktan sonra yeniden denemez - 32 MiB'ye sahip olursunuz. (Kamil'in cevabında olduğu gibi, otomatik olarak yeniden denemek için, belirtmeniz gerekir iflag=fullblock.)


Ayrıca, "tek bir okuma boyutunun ()", tüm tamponun bir kerede belleğe sığması gerektiği anlamına geldiğini, bu nedenle büyük blok boyutlarının aynı zamanda dd ile yapılan büyük bellek kullanımına karşılık geldiğini de unutmayın .

Ve hepsi anlamsızdır, çünkü genellikle 16–32 MiB blokların üstüne çıkarken hiçbir performans elde edemezsiniz - sistemler burada yavaş parça değil, rasgele sayı üretecidir.

Yani basitlik için, sadece kullanın head -c 1G /dev/urandom > output.


7
“... genellikle ~ 16–32 MiB blokların üstüne çıkarken hiçbir performans elde edemezsin” - Tecrübelerime göre, 64-128 kilo baytın üzerindeki performansları çok fazla kazanmama, hatta kaybetmeme eğiliminde oluyorsunuz . Bu noktada, sistem çağrısı maliyetindeki azalan getirilerde iyisiniz ve önbellek çekişmesi rol oynamaya başlar.
mart

3
@marcelm IO performansının blok büyüklüğü 1-2 MB'lık bloklara, bazı durumlarda ise 8 MB'a kadar yükseldiği yüksek performanslı sistemlerin mimarisine yardımcı oldum. LUN başına. Dosya sistemleri birden çok paralel LUN kullanılarak oluşturulduğundan, her biri 1 MB + blok yapan IO için birden fazla iş parçacığı kullanılmasıyla en iyi performansı elde etmek için. Sürdürülen G / Ç oranları 1 GB / sn'nin üzerindeydi. Bunların hepsi dönen disklerdi, bu yüzden blok büyüklüğü 16 hatta 32 MB'lık bloklara çıktıkça yüksek performanslı SSD dizilerinin yutmasını veya veri üretmesini daha hızlı ve daha hızlı olarak görebiliyorum. Kolayca. Belki daha da büyük.
Andrew Henle

4
POSIX yardımcı programınaiflag=fullblock bir GNU uzantısı olduğunu açıkça not edeceğim . Soru Linux'u belirlemediğinden, Linux'a özgü uzantıların kullanımının, açıkça gelecekteki bazı okuyucuların Linux dışı bir sistemde benzer bir sorunu çözmeye çalışarak karıştırılmaması gerektiği açıkça belirtilmesi gerektiğini düşünüyorum. dd
Andrew Henle,

6
@AndrewHenle Ah, ilginç! ddMakinemde 1k - 512M blok boyutlarında hızlı bir test yaptım . Intel 750 SSD'den okuma yaparak, 2MiB bloklarda en iyi performans (yaklaşık 1300MiB / s) elde edildi ve sonuçlara kabaca uyuyor. Daha büyük blok boyutları ne yardımcı ne de engellenmiştir. Okuma /dev/zero, en iyi performans (neredeyse 20GiB / s) 64KiB ve 128KiB bloklarda edildi; hem daha küçük hem de daha büyük bloklar performansı düşürdü ve kabaca önceki yorumuma uyuyordu. Alt satır: gerçek durumunuz için kıyaslama. Ve elbette, ikimiz de kıyaslamadık /dev/random: P
mart

3
@ Xen2050 Biraz daha hızlı testler yaptım ve daha hızlı görünüyor dd. Hızlı bir strace head, 8KiB okuma ve ilginç iki 4KiB yazma kullandığını gösterdi (GNU coreutils, Debian 9.6 / Linux 4.8'de 8.26). headhız gerçekten de dd bs=4kve arasında bir yerdedir dd bs=8k. headhızları karşılaştırıldığında ~% 40 dd if=/dev/zero bs=64kve karşılaştırıldığında ~% 25 azalmıştır dd if=/dev/nvme0n1 bs=2M. Okurlar /dev/zeroelbette daha CPU sınırlıdır, ancak SSD I / O kuyruğu için de bir rol oynar. Beklediğimden daha büyük bir fark var.
marcelm

21

dddaha az okuyabilirsiniz ibs: (not bshem belirtir ibsve obssürece) iflag=fullblockbelirtilir. 0+1 records inolduğunu gösterir 0tam bloklar ve 1kısmen blok okundu. Bununla birlikte, herhangi bir tam veya kısmi blok sayacı arttırır.

Bu özel durumdan dddaha az olan bir blok okumayı sağlayan mekanizmayı tam olarak bilmiyorum 1G. Sanırım herhangi bir blok yazılmadan önce belleğe okunur, bu nedenle bellek yönetimi karışabilir (ancak bu yalnızca bir tahmindir). Düzenleme: bu eşzamanlı cevap , bu özel durumdan dddaha az bir blok okumayı sağlayan mekanizmayı açıklar 1G.

Neyse, bu kadar büyük tavsiye etmiyorum bs. Kullanırdım bs=1M count=1024. En önemli şey şudur: herhangi iflag=fullblock bir okuma girişimi olmadan daha az okuyabilir ibs( ibs=1sanırım, bu olsa da, oldukça yetersiz olduğu sürece ).

Dolayısıyla, kesin miktarda veri okumanız gerekiyorsa, kullanın iflag=fullblock. Not iflagPOSIX tarafından gerekli değildir, sizin dddesteklemeyebilirsiniz. Bu cevaba göre ibs=1, muhtemelen tam bir bayt sayısını okumak için tek POSIX yoludur. Elbette değişirseniz, ibso zaman yeniden hesaplamanız gerekecektir count. Senin durumunda düşürücü ibsiçin 32Mmuhtemelen bile olmadan, sorunu çözecektir veya daha az iflag=fullblock.

Kubuntu'mda emrinizi şu şekilde düzeltirdim:

dd if=/dev/urandom of=output bs=1M count=1024 iflag=fullblock
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.