高性能通信设计实现中的一些共通点

来源:互联网 发布:最便宜的淘宝网 编辑:程序博客网 时间:2024/06/05 12:45

引言

最近一个项目为了实现低时延、高吞吐的目标,自己写了个简单的通信模块。结合实现中的经验和看的一些文章,尝试总结下这个中间一些共通的点,也是做个小结。

备注:我总结时候总是会有一些不同于他人的角度,虽然别人看着可能会比较莫名,但是个人就是写给未来的自己罢了 O(∩_∩)O哈哈~ 
备注2:不要来扯什么中断、线程调度更灵活之类的废话。请麻烦认清楚本文讨论的问题。


1. 避免无谓的CPU消耗

1.1 处理线程绑定CPU core

不论是利用用户态、内核态线程、进程还是自己实现的线程模式,都尽量的避免这中间的调度/切换。主要是为了避免:1.调度消耗 2. 缓存污染,同时有助于实现1.2的原则。

1.2 避免全局变量和其它共享资源

这个当然不完全决定,但是在关键路径上必须的原则。 
结合绑定CPU核,可以避免竞争,也就不需要各种锁、信号量等机制。

1.3 轮询替代中断

直接涉及硬件设备驱动时可用,更适合定制化的系统。要知道一个中断唤醒要3-5us,还不算其它消耗。在高吞吐、高并发下是非常值得采用轮询模式,更可以结合[1.1]将驱动开始就绑定CPU核处理。 
反正就是,一门心思、死心眼的就忙那点事情。多像生产线~~ :) 
说到生产线,就引入另一个点,为了能处理各种不同状况的报文,就需要一个合适的机制给死心眼用

1.4 状态机值得考虑下

就像生产线上,一个产品(报文)流过不同工序(状态),每个工序处理一个任务


2. 提升CPU利用率

2.1 批量处理

如果写个用户态通信实现,那么系统调用(TCP协议栈->硬件驱动)是个非常漫长的过程;如果写个内核态驱动,那么操作硬件,同样也是个无法忍受的等待。如果是单并发的系统,还是那话,不在讨论范围。 
批量化的处理,其实就是折叠了这部分系统调用/硬件等较慢处理的消耗,平摊。1个人要捐1万可能压力山大,10个人就好多,1000个人就是毛毛雨了。 
具体批量处理多少个应根据情况来定,最好有个基准测试和具体的目标,或者可以配置。

2.2 优化内存

要知道内存分配、拷贝甚至查找都是非常耗费时间的。 
但是完全的内存零拷贝并不见得能实现,需要根据具体的系统、目标,甚至硬件来分析具体实现方案。 
但是至少,内存池、大页内存在大部分实现中比较容易达到了。

2.3 免锁实现

嗯,很热门的CAS实现,只是这个硬件锁(原子操作)还是免不掉。同时,如果冲突/竞争几率很高情况下,其实和spinlock也相差无几。 
所以,也许per cpu core的更合适。嗯,至少我还没想好更好的实现,要努力学习呀!

3. 代码层面的手段

不多说

3.1 Cache对齐

目前主流的CPU的cache line都是64B长度的,嗯,一次就是刷这么多。 
读写的cache适当的分离,避免经常改动的部分影响很少变化的部分。 
强烈推荐!

3.2 分支优化(likely/unlikely宏)

小心使用,不完全明确的还是交给CPU自己优化吧

3.3 Cache 预取

在大循环和批量处理,非常有威力。但使用需要些技巧。

3.4 gcc的attribute修饰可以好好研究下

什么__always_inline__,hot之类

多余的话

和查找只会用链表逐个比较的,交流如何高性能本身就是挺扯的事情。这说明俺也是个挺扯的人~~ 
嗯,就这样~!

本文利用在线Cmd Markdown 编辑阅读器完成。 https://www.zybuluo.com/wydnpu/note/18095

0 0
原创粉丝点击