gpt4 book ai didi

c# - 具有异步 UDP 操作的 .NET IOCP 线程池开销

转载 作者:行者123 更新时间:2023-11-30 18:04:27 27 4
gpt4 key购买 nike

我开发了一个 VoIP 媒体服务器,它与远程 SIP 端点交换 RTP 数据包。它需要很好地扩展 - 虽然我最初担心我的 C# 实现不会接近它所取代的 C++ 版本,但我使用了各种分析器来磨练实现并且性能非常接近。

我通过创建可重用对象池来限制大多数对象分配,我正在使用 ReceiveFromAsync 和 SendToAsync 发送/接收数据报,并且我正在使用生产者/消费者队列在系统中传递 RTP 数据包。在配备 2 个 2.4GHz Xeon 处理器的机器上,我现在可以处理大约 1000 个并发流,每个流每秒发送/接收 50 个数据包。然而,迭代配置文件/调整/配置文件让我着迷 - 我确信那里有更高的效率!

触发处理的事件是在 SocketAsyncEventArgs 上调用的 Completed 委托(delegate) - 它反过来通过处理管道发送 RTP 数据包。

剩下的挫折是 IOCP 线程池中似乎有很大的开销。探查器显示只有 72% 的包含采样时间在“我的代码”中 - 之前的时间似乎是线程池开销(下面的堆栈帧)。

所以,我的问题是:

  1. 我是否遗漏了什么?
  2. 是否可以减少这种开销?
  3. 是否可以替换异步套接字函数使用的线程池,以使用开销较小的自定义轻量级线程池?
100% MediaGateway95.35% Thread::intermediateThreadProc(void *)88.37% ThreadNative::SetDomainLocalStore(class Object *)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(struct ADID)86.05% Thread::ShouldChangeAbortToUnload(class Frame *,class Frame *)86.05% AppDomainStack::ClearDomainStack(void)83.72% ThreadPoolNative::CorWaitHandleCleanupNative(void *)83.72% __CT??_R0PAVEEArgumentException@@@8483.72% DispatchCallDebuggerWrapper(unsigned long *,unsigned long,unsigned long *,unsigned __int64,void *,unsigned __int64,unsigned int,unsigned char *,class 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@2081.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(class System.Threading.ExecutionContext,class System.Threading.ContextCallback,object)72.09% System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(object)72.09% System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(class System.Net.Sockets.SocketAsyncEventArgs)

最佳答案

在 Windows 上每秒 50,000 个数据包已经很不错了,我想说硬件和操作系统是扩展的更重要的问题。不同的网络接口(interface)有不同的限制,英特尔服务器 NIC 主要是高性能和良好的跨平台驱动程序,但是与 Linux 相比,Broadcom 在 Windows 上的记录并不好。 Windows 的高级核心网络 API 仅在驱动程序支持这些功能时才会启用,而 Broadcom 已证明是一家只为较新硬件启用高级功能的公司,尽管其他操作系统的旧设备也支持这些功能。

我会开始研究多个 NIC,例如使用四英特尔服务器 NIC,并使用 Windows 高级网络 API 将一个 NIC 绑定(bind)到每个处理核心。理论上,您可以通过一个 NIC 发送 50,000 个,通过另一个 NIC 发送 50,000 个。

http://msdn.microsoft.com/en-us/library/ff568337(v=VS.85).aspx

但是,您似乎并没有真正的基准来衡量代码的效率。我希望看到与不运行 VoIP 负载、在 TCP 传输而非 UDP 上运行以及在其他操作系统上运行的服务器进行比较,以比较 IP 堆栈和 API 效率。

关于c# - 具有异步 UDP 操作的 .NET IOCP 线程池开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6131312/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com