2012-05-02 7 views
0

私は、TCPソケット上で固定長(44バイト)のメッセージを受け取るネットワークデーモンを持っています。LinuxのPerlのsysreadオーバーヘッド

私はsysreadで読んでいるはずのバイト単位の最適な長さを判断しようとしています。私はもちろん44バイトのsysreadを行うループを行うことができますが、私は最適なサイズを考え出したいと思います。

substrを実行するために1メガバイト分のデータがないという利点がありますが、何千ものsysread呼び出しを行うと速度が遅くなることもわかります。

公衆インターネット経由でsysreadを実行するための推奨サイズはありますか?

編集: スクリプトは、44バイトのメッセージの束を取得し、キューに入れられます。

答えて

2

大きい方が良いです! sysreadは、使用可能なバイトがすぐに返されます。

メッセージ全体が保証されることは決してないし、複数のメッセージを持つことは決して保証されないので、Perl側でループする必要があります。 Perl側では既にループがあるので、不要なシステムコールを回避するために、できるだけ多くのデータをシステムから一度に取得することもできます。

use constant READ_SIZE => 65*1024; 

my $buf = ''; 
while (1) { 
    my $rv = sysread($fh, $buf, READ_SIZE, length($buf)); 
    die if !defined($rv); 
    last if !$rv; 

    while ($buf =~ s/^(.{44})//s) { 
     my $msg = $1; 
     process_msg($msg); 
    } 
} 

サイズを選んで$bufのサイズを選んでください。頻繁にREAD_SIZEに近づく場合は、READ_SIZEを増やしてください。

+0

ベンチマークを行った後、これが私のアプリケーションの正解であるようです。 – GoldenNewby

+0

@GoldenNewbyもちろん、Perlにバッファリング自体をさせる(つまり、 'sysread'の代わりに' read''を使って)、おそらくもっと速くなります!私は、 'sysread'が使われるというあなたの前提を盲目的に受け入れました。 – ikegami

+0

http://www.perlmonks.org/?node_id=435814、その議論では、「読んでもファイルの最後を除いてそれをすることはできません」と述べています。 TCPソケットから読み込むという文脈では、それはどういう意味ですか?私は部分的な結果を返すことで大丈夫ですが、一定のバイト数を取得しようとしている間に待つ必要はありません。ノンブロッキング読み出しが可能ですか? – GoldenNewby

0

システムコールは、送信されないバイトをコピーしません。あなたが44バイトのメッセージを持っているなら、perlは常に44バイトの文字列を返します。あなたが提供するサイズは最大値に過ぎず、カーネルに提供されるバッファのサイズを決めるために使われます。 44バイトを超える値を指定すると、複数のメッセージがキューに入れられている場合、それらをすべて単一のシステムコールで取得することができます。

+0

誤解を招くポストの場合、この状況では、44バイトのメッセージが列に並んでいます。それらの何百もあることができます。 – GoldenNewby

+0

'sysread'は44バイト未満を返します。 – ikegami

1

私はオーバーヘッドがどれくらいのものかを確かめていませんが、一方が他のものより速い場合は測定できますが、晴れた青空からサイズを試してみると、まず4092バイトで終わります。それは処理するために最大93のメッセージを与え、それは魔法の4Kbのサイズの下にあります。これは始めるのが良い場所のようです。

プログラムが実行されているシステムでpage sizeが見つかり、それに応じて調整することができます。私はint(PAGE_SIZE/MESSAGE_SIZE)で始まり、それが各メッセージに対して1つよりもsysreadを実行するかどうかを確認します。一方

perl uses 8KB buffers by defaultは:

192 /* The default buffer size for the perlio buffering layer */ 
193 #ifndef PERLIOBUF_DEFAULT_BUFSIZ 
194 #define PERLIOBUF_DEFAULT_BUFSIZ (BUFSIZ > 8192 ? BUFSIZ : 8192) 
195 #endif 

またdiscussion that led to the change有益を見つけるかもしれません。

+0

あなたは「魔法の4KBサイズ」についていくつか光を当てることができますか? – GoldenNewby

+0

私は、使用している多くのシステムが4KBの仮想メモリページサイズを持っていると思います。 –

+0

4KB/8KBバッファは 'sysread'には適用されず、バッファされた読み込みのみが適用されます。 'sysread'は、正確に指定されたサイズの' read'(2)になります。 – ikegami

関連する問題