2017-02-23 1 views
3

나는 약간의 연구를 해왔고 이런 상황이 발생했습니다. STDOUT (화면)에 쓰려면 간단한 단일 스레드 스크립트보다 빠르게 데이터를 인쇄하는 다중 스레드 스크립트를 수행 할 수 없습니다.STDOUT (화면)과 일반 파일을 사용한 성능

myPrinter.perl > myPrint 

결과 변화와 당신은 멀티 스레드 방식이 더 좋은 시간을 가져옵니다 것을 볼 수 있습니다, 당신은이 같은 파일에 기록합니다. STDOUT (화면) 또는 출력 파일이 둘 다 공유 된 자원이므로 액세스 시간이 비슷하지 않을까? 왜 멀티 스레드 접근 방식은 더 나은 파일 쓰기 기능을 수행합니까?

내가 실험에 사용되는 펄 스크립트은 다음과 같습니다

단일 스레드

for my $i (1..100000000){ 
    print("things\n"); 
} 

멀티 스레드

use threads; 
use Thread::Queue 3.01 qw(); 

use constant NUM_WORKERS => 4; 


sub worker { 
    for my $i (1 .. 25000000){ 
     print("things\n"); 
    } 
} 

my $q = Thread::Queue->new(); #::any 

async { while (defined(my $job = $q->dequeue())) { worker($job); } } 
for 1..NUM_WORKERS; 

for my $i (1 .. 4){ 
    $q->enqueue($i); 
} 

$q->end(); 
$_->join for threads->list; 

크레딧 : 큐 구현이 찍은 ...에서 ikegami 중 하나입니다.

+0

[버퍼링에 어려움이 있습니까?] (http://perl.plover.com/FAQs/Buffering.html) – ThisSuitIsBlackNot

+0

"_to the STDOUT_"은 (는) 실제로 화면에 출력하는 것을 의미합니까? 더 오래 걸릴 것입니다. 모든 렌더링, 다시 그리기 및 기타 등등. 시간은 단일 스레드, 화면 대 리디렉션. 멀티 스레드에 어떤 영향을 미치는지는 모르지만 제 추측에 따르면 더 나쁠 수 있습니다. 또한 ThisSuitIsBlack은 버퍼링이 다를 수 있다고 말합니다. – zdim

답변

2

STDOUT에 쓰기가 내부적으로 어떤 형태의 잠금이 필요한 경우에 설명 할 수 있습니다.

STDOUT이 터미널에 연결되면 모든 개행 후에 출력이 플러시됩니다. 그렇지 않으면, STDOUT은 (Perl의 버전에 따라) 4 KiB 또는 8 KiB마다 플러시됩니다.후자의 시나리오는 아마도 더 적은 또는 더 짧은 자물쇠를 필요로했을 것입니다.

동일한 효과를 얻으려면 >file 대신 |cat을 사용할 수 있습니다.

실제 작업자가 STDOUT에 쓰는 시간이 훨씬 적을 경우이 문제는 없어집니다.

1

데이터 출력 속도는 대상 성능에 따라 제한됩니다. 로컬 파일에 기록하는 경우 기본 OS, 파일 시스템 및 디스크 속도에 따라 성능이 제한됩니다. 네트워크 파일 시스템의 파일에 기록하는 경우 네트워크 속도 및 파일 서버 성능에 의해 더 제한됩니다. 일부 OS 레벨 버퍼링을 사용하면이 속도가 빨라집니다.

STDOUT에 쓰는 경우 STDOUT의 대상이 무엇인지에 따라 다릅니다. STDOUT은 파일로 재 지정되고 다른 프로세스로 파이프되며 또한 터미널에 인쇄 될 수 있습니다. 이 모든 경우에 쓰기 속도는 대상 매체에 따라 달라집니다. 터미널은 보통 로컬 파일에 비해 서면으로 매우 느립니다. 그러나 다시 말하지만, 이것은 STDOUT 대 파일이지만 STDOUT이 끝나는 곳의 문제는 아닙니다.

+0

네, 맞습니다. STDOUT을 쓸 때 화면에서 생각하고 있다는 것을 분명히해야합니다. 나는 각 리소스마다 다른 한계가 있음을 알고 있지만 화면에 쓰기와 파일 쓰기의 차이점을 알고 싶습니다. 나는 zdim이 그 의견에 그것을 가지고 있다고 생각한다. –

+0

@ IvánRodríguezTorres : 이것은 문제가 Perl 및 STDOUT과 완전히 관련이 없다는 것을 의미하지만 터미널로의 얼마나 빠른 출력이 파일의 출력에 의존하는지 묻습니다. –

2

예를 들어, 내 의견을 따르십시오. 나는 질문에서 당신이 STDOUT 인쇄물이 터미널로 감겨지는 내용과 파일로 리디렉션 된 내용을 비교한다는 것을 이해합니다.

는 콘솔에서 실행

time perl -we'print "hello\n" for 1..1_000_000' 

시간 :   0.209u 1.562s 0:17.65 9.9% 0+0k 0+0io 0pf+0w   (tcsh의)

time perl -we'print "hello\n" for 1..1_000_000' > many_writes.out 

시간 : 17.65 초 대 0.11초이다   0.104u 0.005s 0:00.11 90.9% 0+0k 0+11720io 0pf+0w

. 터미널에 인쇄하는 것은 매우 느립니다.

여러 스레드에서 나는 그 차이가 훨씬 더 분명해질 것으로 기대합니다.

+0

예, 나는이 시험도했다. 나는 당신의 의견이 좋은 지적이라고 생각합니다. 조금 더 읽은 후에 병목 현상이 렌더링 프로세스에 있다고 생각합니다. –