dd는 1GB 대신 32MB의 임의 파일을 생성합니다.


50

1GB의 임의 파일을 생성하고 싶었으므로 다음 명령을 사용했습니다.

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

그러나 대신이 명령을 시작할 때마다 32MB 파일이 생성됩니다.

<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

뭐가 잘못 되었 니?

편집하다:

이 주제에 대한 큰 답변 덕분에 32GB를 32MB로 읽는 솔루션이 제공되어 1GB가됩니다.

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

1GB를 메모리로 직접 읽은 다음 디스크에 쓰는 다른 솔루션이 제공되었습니다. 이 솔루션은 많은 메모리를 사용하므로 선호되지 않습니다.

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

3
IMHO 나는 많은 유효한 유스 케이스가 전혀 없다고 생각 dd합니다. 내가 사용하는 것 head, cat또는 rsync거의 항상 그 자리한다. 대안이 일반적으로 더 안전한 이유 중 하나 인 경우 귀하의 질문.
Bakuriu

@Bakuriu-또한 0으로 가득 찬 파일을 생성하려면 (또는 그 안에 무엇이 있는지 신경 쓰지 않으려면) 잘라내기를 사용하십시오. 훨씬 빠릅니다.
Konrad Gajewski

@KonradGajewski FYI truncate는 스파 스 파일을 만들려고합니다 (중요한 경우)
Xen2050

5
@Bakuriu headPOSIX에없는-c 옵션 없이는이 작업을 수행 할 수 없습니다 . 나는 이것을 해결할 수 있는 버전을 모른다 . 완전히 비표준 유틸리티입니다. 그것은 여기에 없습니다. 매뉴얼 페이지를 살펴보면이 문제를 어떻게 해결할 수 있는지 알지 못합니다. catrsync
Kaz

기술적 /dev/urandom으로도 POSIX에도 없습니다.
grawity

답변:


92

bs버퍼 크기 는 dd가 수행 한 단일 read () 호출 의 크기를 의미합니다 .

(예를 들어, 모두 bs=1M count=1bs=1k count=1k1 개 MIB 파일을 초래할 것이지만, 제 1024 개 작은 덩어리를 수행 할 때 첫 번째 버전은 단일 단계에서 수행된다.)

일반 파일은 거의 모든 버퍼 크기로 읽을 수 있지만 (버퍼가 RAM에 맞는 경우) 장치 및 "가상"파일은 종종 개별 호출에 매우 가깝게 작동하며 데이터 당 생성되는 데이터의 양에 대한 임의의 제한이 있습니다. read () 호출.

/dev/urandom경우이 한계는 drivers / char / random.c의 urandom_read () 에 정의되어 있습니다 .

#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));
    ...
}

이것은 함수가 호출 될 때마다 요청 된 크기를 33554431 바이트로 고정한다는 것을 의미합니다.

기본적으로 다른 대부분의 도구와 달리 dd 는 요청한 것보다 적은 데이터를받은 후에 다시 시도하지 않습니다. 32MiB를 얻으면 그게 전부입니다. (Kamil의 답변 에서처럼 자동으로 다시 시도하려면을 지정해야합니다 iflag=fullblock.)


또한 "단일 read ()의 크기"는 전체 버퍼가 한 번에 메모리에 맞아야한다는 것을 의미하므로 대규모 블록 크기는 dd의 대규모 메모리 사용량과도 일치합니다 .

~ 16-32 MiB 블록 이상으로 올라갈 때 일반적으로 성능을 얻지 못하기 때문에 모든 것이 의미가 없습니다. 여기서 syscall은 느린 부분이 아니며 난수 생성기입니다.

따라서 간단하게하려면을 사용하십시오 head -c 1G /dev/urandom > output.


7
"위 ~ 16-32의 MIB 블록을 갈 때 ... 당신은 일반적으로 어떤 성능을 얻을 수 없습니다" - 내 경험에 의하면, 당신은 64-128 위의 성능을 잃고도 많이 얻을, 또는하지 않는 경향이 킬로 바이트. 이 시점에서, 당신은 wrt syscall 비용의 감소를 잘 알고 있으며 캐시 경합이 역할을 시작합니다.
marcelm

3
@marcelm 저는 블록 크기가 1-2MB 블록으로 증가하고 경우에 따라 최대 8MB 정도까지 IO 성능이 향상되는 고성능 시스템을 설계하는 데 도움을주었습니다. LUN 당. 또한 파일 시스템이 여러 개의 병렬 LUN을 사용하여 구성되었으므로 각각 1MB 이상의 블록을 수행하는 IO에 여러 스레드를 사용하여 최상의 성능을 얻을 수 있습니다. 지속적인 IO 속도는 1GB / 초를 초과했습니다. 그리고 이것들은 모두 회전하는 디스크 였으므로 블록 크기가 16MB 또는 32MB 블록으로 증가함에 따라 고성능 SSD 어레이가 데이터를 더 빠르게 삼키거나 생성하는 것을 볼 수 있습니다. 용이하게. 아마 더 클 수도 있습니다.
Andrew Henle

4
나는 명시 적으로주의하겠습니다 iflag=fullblock에 GNU 확장이다 는 POSIX의 dd유틸리티 . 이 질문에 Linux가 명시되어 있지 않기 때문에 Linux가 아닌 시스템에서 비슷한 문제를 해결하려는 미래의 독자가 혼동하지 않도록 Linux 관련 확장 사용을 명시 적으로 언급해야한다고 생각합니다.
Andrew Henle

6
@AndrewHenle 아, 재미 있어요! 나는 dd1k에서 512M의 블록 크기로 내 컴퓨터에서 빠른 테스트를 수행 했습니다. Intel 750 SSD에서 읽은 결과 2MiB 블록에서 최적의 성능 (약 1300MiB / s)이 달성되어 결과와 거의 일치합니다. 더 큰 블록 크기는 도움이되지도 방해하지도 않았습니다. 에서 읽기 /dev/zero, 최적의 성능을 (거의 20GiB / S) 64KiB 및 128KiB 블록에되었다; 모두 작은 더 큰 블록은 대략 내 이전 의견을 일치, 성능이 저하. 결론 : 실제 상황에 대한 벤치 마크. 그리고 물론, 우리 둘은 벤치 마크 /dev/random: P
marcelm을

3
@ Xen2050 좀 더 빠른 테스트를했는데 더 dd빠릅니다. 빠른 head추적은 8KiB 읽기와 두 개의 4KiB 쓰기 를 사용하는 것으로 나타났습니다 (데비안 9.6 / Linux 4.8의 GNU coreutils 8.26). head속도는 실제로 ~ 사이 dd bs=4kdd bs=8k있습니다. head속도는 ~ 40 % dd if=/dev/zero bs=64k감소했으며 ~ 25 % 감소했습니다 dd if=/dev/nvme0n1 bs=2M. 읽기 /dev/zero는 물론 CPU 제한이 많지만 SSD I / O 대기열도 중요한 역할을합니다. 예상보다 큰 차이입니다.
marcelm

21

dd를 지정 하지 않으면 보다 작게 읽을 수 있습니다 ibs(주 : 와 bs모두 지정). 전체 블록 및 부분 블록을 읽었 음을 나타냅니다 . 그러나 전체 또는 부분 블록은 카운터를 증가시킵니다.ibsobsiflag=fullblock0+1 records in01

나는 이 특별한 경우 dd보다 적은 블록을 읽는 정확한 메커니즘을 모른다 1G. 블록을 작성하기 전에 블록을 메모리로 읽은 것으로 추측되므로 메모리 관리가 방해를받을 수 있습니다 (그러나 이것은 추측 일뿐입니다). 편집 : 이 동시 답변 은이 특별한 경우 dd보다 적은 블록을 읽는 메커니즘을 설명합니다 1G.

어쨌든, 나는 그렇게 큰 것을 권장하지 않습니다 bs. 사용 bs=1M count=1024합니다. 가장 중요한 것은 :없이 iflag=fullblock 어떤 읽기 시도가보다 읽을 수 있습니다 ibs(하지 않는 한 ibs=1나는이 비록 매우 비효율적 인 생각을).

따라서 정확한 양의 데이터를 읽어야하는 경우을 사용하십시오 iflag=fullblock. 참고가 iflagPOSIX에 의해 필요하지 않습니다, 당신은 dd그것을 지원하지 않을 수 있습니다. 이 대답 에 따르면 ibs=1아마도 정확한 바이트 수를 읽는 유일한 POSIX 방법 일 것입니다. 물론 변경 ibs하면을 다시 계산해야합니다 count. 귀하의 경우 ibs32M또는 이하로 낮추면 아마도 없이도 문제를 해결할 수 iflag=fullblock있습니다.

쿠분투에서는 다음과 같이 명령을 수정합니다.

dd if=/dev/urandom of=output bs=1M count=1024 iflag=fullblock
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.