2017-08-08 18 views
0

私はLinuxのボックスで.NETコアのパフォーマンスを調べています。具体的には、どのような制限がフレームワーク内で利用できるツールであるかを確認することです。UDPClientのスループットを向上させる方法

私は〜50,000 ppsで箱を打っています。これまでのところ、パケットのかなりのビットが落とされる前にUDPClientが達成できたのは約20,000ppsです。別のツール(syslog-ng)を使用すると、まれな/低いパケット損失率があります。

もし私が50K pps以上を処理しようとしているのであれば、UdpClientはこれを適切なチューニングで処理できますか?

using (UdpClient udpListener = new UdpClient(_sysLogPort)) 
{ 
    udpListener.Client.ReceiveBufferSize = _bufferSize; 

    while (!_cts.IsCancellationRequested) 
    { 
     try 
     { 
      UdpReceiveResult result = await udpListener.ReceiveAsync(); 
     } 
     catch (Exception ex) 
     { 

     } 
    } 
} 
+0

あなたの主な武器はSO_RCVBUFSIZ経由でソケット受信バッファーのサイズを増やすことですが、使用しているAPIに表示されます。 – EJP

+0

@EJP ReceiveBufferSizeプロパティはこれを処理する部分(私は間違っている可能性があります)が、送信される現在のパケットはかなり小さく、バッファ制限は現在送信されているパケットよりもはるかに大きいと考えています。これは、syslog-ngがこのトラフィックを非常に少ないオーバーフローで処理できるようになったので、おそらくUdpClientに欠けているようなチューニングのような感じです。 –

+0

このプログラムにパケットを送信するために使用しているパケットサイズは?どのツールでこれらのパケットを送信していますか?どのプロセッサタイプを使用していますか?ループバックインターフェイスを使用していることを確認できますか(つまり、送信者とプログラムは同じLinuxホストにあります)。あなたのLinuxボックスで、どのバージョンのドットネットを使用していますか?1.0.4、より古い、より最近ですか? –

答えて

1

あなたのアプリがudpListener.ReceiveAsync();で新しいスレッドを起動した場合でも、それは新しいパケットを受信しようとする前に、その終了を待ちます。したがって、新しい受信UDPパケットを処理してUdpReceiveResult型のオブジェクトを作成するスレッドは一度に1つしかありません。したがって、シングルスレッドのアプリに似ています。ではなく、で、マルチコアシステムで実行する機会を利用します。

(ハードウェアによっては、明らかに)次の方法でプログラムを書くことができます。この例では、同時に実行される5つのスレッドのプールがあり、UdpReceiveResultの複数のインスタンスを同時に作成しています。パケットが一度に1つずつカーネルによって処理されたとしても、UdpReceiveResultのインスタンスを作成するユーザランドプロセスは、このプログラミング方法で並列に実行されます。

// example of multithreaded UdpClient with .NET core on Linux 
// works on Linux OpenSuSE LEAP 42.1 with .NET Command Line Tools (1.0.4) 
// passed tests with "time nping --udp -p 5555 --rate 2000000 -c 52000 -H localhost > /dev/null" 

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 

namespace hwapp { 
    class Program { 
    // listen to port 5555 
    UdpClient udpListener = new UdpClient(5555); 

    static void Main(string[] args) { 
     Program p = new Program(); 
     // launch 5 threads 
     Task t0 = p.listen("thread 0"); 
     Task t1 = p.listen("thread 1"); 
     Task t2 = p.listen("thread 2"); 
     Task t3 = p.listen("thread 3"); 
     Task t4 = p.listen("thread 4"); 
     t0.Wait(); t1.Wait(); t2.Wait(); t3.Wait(); t4.Wait(); 
    } 

    public async Task listen(String s) { 
     Console.WriteLine("running " + s); 
     using (udpListener) { 
     udpListener.Client.ReceiveBufferSize = 2000; 
     int n = 0; 
     while (n < 10000) { 
      n = n + 1; 
      try { 
      UdpReceiveResult result = udpListener.Receive(); 
      } catch (Exception ex) {} 
     } 
     } 
    } 
    } 
} 
関連する問題