当前位置:  开发笔记 > 编程语言 > 正文

.NET套接字与C++套接字的高性能

如何解决《.NET套接字与C++套接字的高性能》经验,为你挑选了2个好方法。

我的问题是与我的同事讨论C++与C#的争论.

我们已经实现了一个接收大量UDP流的服务器.此服务器使用异步套接字和使用完成端口的重叠I/O在C++中开发.我们使用5个完成端口和5个线程.该服务器可以轻松处理千兆网络上的500 Mbps吞吐量,而不会丢失数据包/错误(我们没有将测试推送到500 Mbps以上).

我们尝试在C#中重新实现相同类型的服务器,但我们无法达到相同的传入吞吐量.我们使用异步接收使用ReceiveAsync方法和池SocketAsyncEventArgs来避免为每个接收调用创建新对象的开销.每个SAEventArgs都有一个缓冲区设置,所以我们不需要为每次接收分配内存.该池非常非常大,因此我们可以排队超过100个接收请求.此服务器无法处理超过240 Mbps的传入吞吐量.超过该限制,我们在UDP流中丢失了一些数据包.

我的问题是:我应该期望使用C++套接字和C#套接字获得相同的性能吗?我的观点是,如果在.NET中正确管理内存,它应该是相同的性能.

附带问题:有人会知道一篇很好的文章/参考资料,解释.NET套接字如何使用I/O完成端口吗?



1> Richard..:

有人会知道一篇很好的文章/参考资料,解释.NET套接字如何使用I/O完成端口吗?

我怀疑唯一的参考是实现(即Reflector或其他程序集解编译器).通过这种方式,您会发现所有异步IO都通过IO完成端口,并在IO线程池(与正常线程池分开)中处理回调.

使用5个完成端口

我希望使用单个完成端口将所有IO处理成单个线程池,每个池有一个线程服务完成(假设您正在执行任何其他IO,包括磁盘,也是异步).

如果您正在进行某种形式的优先级排序,则有多个完成端口是有意义的.

我的问题是:我应该期望使用C++套接字和C#套接字获得相同的性能吗?

是或否,取决于您定义"使用...套接字"部分的范围.从异步操作开始到完成发布到完成端口的操作方面,我预计没有显着差异(所有处理都在Win32 API或Windows内核中).

但是,.NET运行时提供的安全性会增加一些开销.例如.将检查缓冲区长度,验证代理等.如果应用程序的限制是CPU,那么这可能会有所不同,并且在极端情况下,很小的差异可以很容易地加起来.

此外,.NET版本偶尔会暂停GC(.NET 4.5会进行异步收集,因此将来会变得更好).存在最小化垃圾累积的技术(例如,重用对象而不是创建它们,在避免装箱的同时利用结构).

最后,如果C++版本正常工作并且满足您的性能需求,为什么要端口?



2> jgauffin..:

你不能直接从C++到C#的代码端口,并期望相同的性能.在内存管理(GC)和确保代码安全(边界检查等)方面,.NET比C++做得更多.

我会为所有IO操作分配一个大缓冲区(例如65535 x 500 = 32767500字节),然后为每个SocketAsyncEventArgs(和发送操作)分配一个块.内存比CPU便宜.使用缓冲区管理器/工厂为所有连接和IO操作(Flyweight模式)提供块.Microsoft在他们的Async示例中执行此操作.

Begin/End和Async方法都在后台使用IO完成端口.后者不需要为每个提高性能的操作分配对象.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有