网络代码与应用中的调度与上下文切换开销优化
1. 网络代码中避免调度开销
1.1 协议实现的挑战
在实现协议时,一个主要难题是平衡模块化和性能。以网络栈实现为例,若将传输协议(如 TCP)、路由协议(如 IP)和应用分别作为独立进程实现,每个接收到的数据包至少需要两次进程上下文切换,这会带来较高的开销。
1.2 Clark 的创新方案
Dave Clark 提出了一种创新方法,以一个简单应用为例,该应用从键盘读取数据,通过可靠传输协议发送到网络,接收方收到数据后显示在屏幕上。传统的实现方式是每个协议层对应一个进程,这样每个数据包的收发会涉及三个进程和两次完整的上下文切换。
而 Clark 建议在发送方和接收方分别使用两个进程来实现网络协议栈:
- 发送方 :有一个键盘处理进程,它收集键盘输入的数据,当有数据时调用 transport-arm-to-send
函数。该函数是传输层导出给键盘处理进程的函数,执行时键盘处理进程可暂停自身。 transport-arm-to-send
仅告知传输协议该连接要发送数据,不进行数据传输。当流量控制限制解除后,发送进程执行 transport-send
例程,该例程会先调用应用协议的 display-get-data
函数获取数据,然后添加传输层头部并调用网络协议发送数据包。
- 接收方 :接收中断处理程序使用 net-dispatch
例程接收数据包,该