Tee가 파이프라인 속도를 늦출까요?

Tee가 파이프라인 속도를 늦출까요?

티가 파이프 속도를 늦추는지 궁금합니다. 결국, 디스크에 데이터를 쓰는 것은 파이프를 통해 보내는 것보다 느립니다.

데이터가 디스크에 기록될 때까지 다음 파이프로 데이터를 보내기 위해 대기합니까? (그렇지 않다면 티는 전송되었지만 디스크에 기록되지 않은 데이터를 대기열에 넣어야 할 것 같은데, 제 생각엔 그럴 것 같지 않습니다.)

$ program1 input.txt | tee intermediate-file.txt | program2 ...

답변1

예, 속도가 느려질 것입니다. 기본적으로 기록되지 않은 데이터의 대기열이 있지만 실제로는 커널에 의해 유지관리됩니다. 명시적으로 달리 요청하지 않는 한 모든 프로그램에는 이 대기열이 있습니다.

예를 들어, 여기에 사용된 간단한 파이프가 있는데 pv, 이는 전송 속도를 보여주기 때문에 좋습니다.

$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null 
  50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%

tee이제 추가 사본을 작성하지 않고 여기에 하나를 추가해 보겠습니다 . 전달하기만 하면 됩니다.

$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null 
  50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%            

그래서 이것은 약간 느리고 아무것도 하지 않습니다! 이는 티의 내부 STDIN을 STDOUT으로 복사하는 오버헤드입니다. (흥미롭게 pv도 거기에 두 번째 것을 추가하면 여전히 5.19GiB/s가 유지되므로 . 를 사용하는 것 pv보다 훨씬 빠르지 만 아마도 그렇지 않을 것입니다.)teepvsplice(2)tee

tee어쨌든, 디스크에 있는 파일에 쓰라고 하면 어떻게 되는지 봅시다 . 처음에는 매우 빠르게 시작되지만(~800MiB/s) 시간이 지남에 따라 속도가 계속 느려지고 결국 약 100MiB/s로 내려갑니다. 이는 기본적으로 디스크 쓰기 대역폭의 100%입니다. (빠른 시작은 커널 캐싱 디스크 쓰기로 인한 반면, 느린 디스크 쓰기는 커널이 캐시가 무한정 커지는 것을 거부하기 때문에 발생합니다.)

그게 그렇게 중요한 건가?

위의 경우는 최악의 경우입니다. 위의 내용은 파이프를 사용하여 가능한 한 빨리 데이터를 내보냅니다. 내가 생각할 수 있는 유일한 실제 사용은 원시 YUV 데이터를 ffmpeg.

데이터를 처리하는 등의 이유로 더 느린 속도로 데이터를 보내면 영향이 훨씬 적습니다.

답변2

결국 여기엔 이상한 게 하나도 없어

>POSIX 라고,

설명하다

이것유틸리티는 표준 입력을 표준 출력으로 복사하여 0개 이상의 파일을 복사해야 합니다.이것유틸리티는 출력을 버퍼링해서는 안 됩니다.

그리고그리고 그거

근본적인

버퍼링 요구 사항은 tee가 ISO C 표준 완전 버퍼링 또는 라인 버퍼링 쓰기를 사용할 수 없음을 의미합니다. 이는 티가 먼저 1바이트 읽기를 수행한 다음 1바이트 쓰기를 수행해야 한다는 의미는 아닙니다.

따라서 "기본"을 설명하지 않고 tee그냥 읽고 쓸 수도 있습니다.아무리바이트는 한 번에 파이프 버퍼에 들어갈 수 있습니다.쓸 때마다 출력을 플러시합니다.

예, 애플리케이션에 따라 이는 매우 비효율적일 수 있습니다. 따라서 다음 중 하나를 제거/주석 처리하시기 바랍니다.
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224

관련 정보