2017-02-23 4 views
3

私はいくつかの調査を行っており、この状況があります。 STDOUT(画面)に書きたい場合は、単純なシングルスレッドスクリプトより速くデータを出力するマルチスレッドスクリプトを実行することはできません。しかし、次のようなファイルに書き込むと、STDOUT(スクリーン)と通常のファイルを使用したパフォーマンス

myPrinter.perl > myPrint 

結果が変わって、マルチスレッドの方が時間がかかることがわかります。私の疑問は、STDOUT(画面)または出力ファイルが両方とも共有リソースなので、アクセス時間は同じではないでしょうか? なぜマルチスレッドのアプローチはファイルへの書き込みを改善するだけですか?私は実験で使用し

Perlスクリプトは以下のとおりです。

シングルスレッド

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

[バッファリングに苦しんでいますか] – ThisSuitIsBlackNot

+0

「_to the STDOUT_」とはどういう意味ですか?実際に画面に表示されますか?それは、すべてのレンダリング、再描画などに時間がかかります。シングルスレッドの時間を、スクリーンとリダイレクトされた時間に合わせる。私はそれがマルチスレッドにどのような影響を与えるのか分かりませんが、私の推測ではそれはもっと悪くなるだけです。また、ThisSuitIsBlackNotによると、バッファリングは異なる場合があります。 – zdim

答えて

2

これは、STDOUTへの書き込みに何らかの形式のロックが必要な場合に説明できます。

STDOUTが端末に接続されている場合、改行ごとに出力がフラッシュされます。それ以外の場合は、STDOUTは4 KiBまたは8 KiBごとにフラッシュされます(Perlのバージョンによって異なります)。後者のシナリオでは、より少ないまたはより短いロックが必要になると思われる。

>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

うん、私もこのテストをした。私はあなたのコメントが良い点を作ると思う。もう少し読んだら、ボトルネックはレンダリングプロセスにあると思います。 –

関連する問題