リモート SIP エンドポイントと RTP パケットを交換する VoIP メディア サーバーを開発しました。適切にスケーリングする必要があります。最初は、私の C# 実装が置き換えられる C++ バージョンに近づかないのではないかと懸念していましたが、さまざまなプロファイラーを使用して実装を磨き上げたところ、パフォーマンスはかなり近くなりました。
再利用可能なオブジェクトのプールを作成することで、ほとんどのオブジェクト割り当てを排除しました。ReceiveFromAsync と SendToAsync を使用してデータグラムを送受信し、プロデューサー/コンシューマー キューを使用してシステム内で RTP パケットを渡しています。2 x 2.4GHz Xeon プロセッサを搭載したマシンで、約 1000 の同時ストリームを処理できるようになりました。各ストリームは毎秒 50 パケットを送受信します。しかし、反復的なプロファイル/微調整/プロファイルにはまってしまいました - そして、どこかでもっと効率的であると確信しています!
処理をトリガーするイベントは、SocketAsyncEventArgs で呼び出される Completed デリゲートです。次に、処理パイプラインを介して RTP パケットを送信します。
残りのフラストレーションは、IOCP スレッドプールにかなりのオーバーヘッドがあるように見えることです。プロファイラーは、インクルーシブ サンプル時間の 72% のみが「私のコード」にあることを示しています。それ以前の時間は、スレッドプールのオーバーヘッドのようです (以下のスタック フレーム)。
だから、私の質問は次のとおりです。
- 私の理解に何か欠けていますか?
- このオーバーヘッドを削減することは可能ですか?
- 非同期ソケット関数で使用されるスレッドプールを置き換えて、オーバーヘッドの少ないカスタムの軽量スレッドプールを使用することは可能ですか?
100% メディアゲートウェイ 95.35% Thread::intermediateThreadProc(void *) 88.37% ThreadNative::SetDomainLocalStore(クラス オブジェクト *) 88.37% BindIoCompletionCallbackStub(unsigned long,unsigned long,struct _OVERLAPPED *) 86.05% BindIoCompletionCallbackStubEx(unsigned long,unsigned long,struct _OVERLAPPED *,int) 86.05% ManagedThreadBase::ThreadPool(struct ADID,void (*)(void *),void *) 86.05% CrstBase::Enter(void) 86.05% AppDomainStack::PushDomain(構造体 ADID) 86.05% Thread::ShouldChangeAbortToUnload(class Frame *,class Frame *) 86.05% AppDomainStack::ClearDomainStack(ボイド) 83.72% ThreadPoolNative::CorWaitHandleCleanupNative(void *) 83.72% __CT??_R0PAVEEArgumentException@@@84 83.72% DispatchCallDebuggerWrapper(unsigned long *,unsigned long,unsigned long *,unsigned) __int64,void *,unsigned __int64,unsigned int,unsigned char *,クラス ContextTransitionFrame *) 83.72% DispatchCallBody(unsigned long *,unsigned long,unsigned long *,unsigned __int64,void *,unsigned __int64,unsigned int,unsigned char *) 83.72% MethodDesc::EnsureActive(void) 81.40% _CallDescrWorker@20 81.40% System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint32,uint32,valuetype System.Threading.NativeOverlapped*) 76.74% System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(uint32,uint32,valuetype System.Threading.NativeOverlapped*) 76.74% System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess (valuetype System.Net.Sockets.SocketError,int32,valuetype System.Net.Sockets.SocketFlags) 74.42% System.Threading.ExecutionContext.Run(クラス System.Threading.ExecutionContext,クラス System.Threading.ContextCallback,object) 72.09% System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(オブジェクト) 72.09% System.Net.Sockets.SocketAsyncEventArgs.OnCompleted (クラス System.Net.Sockets.SocketAsyncEventArgs)