vpp 使用矢量包处理开发的,而不是标量包处理。
矢量包处理是高性能包处理应用中常用的方法,比如VPP和DPDK。基于标量包处理的方法往往受到非严格性能要求的网络堆栈的青睐。
Scalar Packet Processing(标量包处理)
标量数据包网络堆栈通常一次处理一个数据包:中断处理函数从网络接口获取单个数据包,并通过一组函数处理它:fooA调用fooB调用fooC等等。
+---> fooA(packet1) +---> fooB(packet1) +---> fooC(packet1)
+---> fooA(packet2) +---> fooB(packet2) +---> fooC(packet2)
...
+---> fooA(packet3) +---> fooB(packet3) +---> fooC(packet3)
标量包处理很简单,但在以下方面效率低下:
- 当代码路径长度超过微处理器指令缓存(I-cache)的大小时,随着微处理器不断加载新指令,抖动就会发生。在这个模型中,每个数据包都会导致一组相同的I-cache缺失。
- 相关的深度调用堆栈也会增加加载-存储单元的压力,因为堆栈局部值从微处理器的第一层数据缓存(D-cache)中掉出来。
Vector Packet Processing(矢量包处理)
相反,矢量包处理网络堆栈一次处理多个数据包,被称为数据包矢量或者矢量。中断处理函数从网络接口获取数据包矢量(一次获取多个数据包,数据包用矢量指针管理,dpdk通常使用轮询方式取报文),并通过一组函数处理向量:fooA调用fooB调用fooC等等。
+---> fooA([packet1, +---> fooB([packet1, +---> fooC([packet1, +--->
packet2, packet2, packet2,
... ... ...
packet256]) packet256]) packet256])
此方法弥补了上面讲到的缺陷:
- 上面描述的I-cache抖动问题,通过在多个数据包上分摊I-cache负载的成本。
- 通过一次从网络接口接收多达256个数据包矢量,并使用节点有向图处理它们,解决深度调用堆栈相关的低效率。图调度器一次调用一个节点调度函数,将堆栈深度限制为几个堆栈帧。
这种方法支持的进一步优化是流水线和预取,以最大限度地减少表数据的读取延迟和并行化数据包加载所需的数据包负载。
按下一步查看有关包处理图的更多信息。