0

TCP ソケットで固定長 (44 バイト) のメッセージを受信するネットワーク デーモンがあります。

sysread で読み取る必要があるバイト単位の最適な長さを判断しようとしています。もちろん、44 バイトの sysread を実行するループを実行できますが、最適なサイズを見つけたいと考えています。

substr を実行するメガバイトに値するデータを言わないことの利点はわかりますが、1000 回の sysread 呼び出しを実行すると速度が低下する理由もわかります。

パブリック インターネット経由で sysreads を実行するための適切なサイズの推奨事項はありますか?

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

4

3 に答える 3

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ます。

于 2012-05-03T03:10:55.913 に答える
1

オーバーヘッドが何であるかはわかりません。一方が他方よりも速いかどうかを測定できるのはあなただけですが、澄んだ青い空からサイズを試すとしたら、4092最初にバイトを使用します. これにより、最大 93 個のメッセージを処理することができ、魔法の 4Kb サイズ未満であり、開始するのに適しているように思えます。

プログラムが実行されているシステムのページ サイズを確認し、それに応じて調整できます。まず、メッセージごとにint(PAGE_SIZE / MESSAGE_SIZE)1 つよりも優れたパフォーマンスを発揮するかどうかを確認します。sysread

一方、perlデフォルトで 8KB のバッファを使用します

 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

また、変更につながった議論が参考になる場合もあります。

于 2012-05-03T00:48:03.983 に答える
0

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

于 2012-05-03T00:01:36.083 に答える