Linux 中的高性能数据包处理



我正在使用BeagleBone Black在Linux中做一个数据包重塑项目。基本上,数据包在一个VLAN上接收,修改,然后在另一个VLAN上发送出去。此过程是双向的 - VLAN 未指定为仅输入或仅输出。它类似于网桥,但数据包在传输过程中会发生变化(有时相当显着)。

我尝试了两种不同的方法来实现这一目标:

  1. 创建在两者上打开原始套接字的用户空间应用程序接口。所有数据包处理(包括桥接)都在应用程序。
  2. 设置软件桥(使用内核桥接模块)并添加安装网络过滤器的内核模块后路由中的挂钩 (NF_BR_POST_ROUTING)。所有数据包处理都是在内核中处理。

第二个选项似乎比第一个选项快 4 倍左右。我想更多地了解为什么会这样。我尝试过头脑风暴,想知道在内核和用户空间之间快速切换是否会对性能造成重大影响,或者套接字接口的某些东西本质上很慢?

我认为用户应用程序已经相当优化(例如,我正在使用PACKET_MMAP),但有可能进一步优化。我在应用程序上运行了 perf,并注意到它在v7_flush_kern_dcache_area上花费了大量时间 (35%),所以也许这是一个可能的候选者。如果对优化数据包处理的常用方法有任何其他建议,我可以尝试一下。

上下文切换是昂贵的,内核到用户空间的切换意味着上下文切换。您可以查看本文以获取确切的数字,但规定的持续时间均以微秒为单位。

您还可以使用 lmbench 对特定 CPU 上上下文切换的实际成本进行基准测试。

用户空间应用程序的性能也取决于用于监视套接字的系统调用。最快的系统调用是 epoll() 当你需要处理大量套接字时。select() 如果处理大量套接字,则性能将非常差。

请参阅这篇文章解释它:为什么 epoll 比选择快?

最新更新