天天看点

C#高性能大容量SOCKET并发(四):缓存设计

在编写服务端大并发的应用程序,需要非常注意缓存设计,缓存的设计是一个折衷的结果,需要通过并发测试反复验证。有很多服务程序是在启动时申请足够的内存空间,避免在运行期间再申请空间,这种是固定空间申请。还有一种是在运行期间动态增长的缓存设计,随着运行动态申请内存,这种事动态空间申请。这两种机制各有优劣,固定空间申请优点是效率高,运行稳定,缺点是对应用场景具有限制;动态空间申请优点是能适应更好的应用场景,缺点是效率相对低一些,并发数降一些;这种性能下降不是太明显,毕竟申请释放内存的效率NET是有优化的,具体需要根据应用场景设计。

在C#版IOCP中我们结合了固定缓存设计和动态缓存设计,其中服务端支持连接数使用了固定缓存设计(AsyncSocketUserTokenPool),根据程序启动时设置的最大连接数申请固定个数的对象。其中接收数据缓存(DynamicBufferManager m_receiveBuffer)、发送数据列表(AsyncSendBufferManager m_sendBuffer)是随着接收数据大小动态增长。

固定缓存设计

固定缓存设计我们需要建立一个列表进行,并在初始化的时候加入到列表中,实现非常简单,列出代码供参考。

初始化加入列表的代码如下:

动态缓存设计

动态缓存是随着数据量大小动态增长,申请的内存在运行过程中重复利用,不释放,这样对内存只进行读写,不进行申请和释放,整体性能较高,因为内存申请释放比读写的效率低很多,因为申请释放内存需要进行加锁,进行系统内核和用户切换,因此使用动态缓存可以降低内核和用户态切换,提高性能。动态缓存的代码如下:

异步发送列表

异步发送列表是在动态缓存的基础上加了一个列表管理,记录每个包的位置信息,并提供管理函数,代码示例如下: