UDP端口的低延迟读取

时间:2011-12-06 13:15:53

标签: c++ boost boost-asio latency

我正在从UDP端口读取单个数据项。这次读取必须尽可能地降低延迟。目前我正在通过boost :: asio库的async_receive_from方法阅读。有谁知道我到达网卡的数据包与我的用户代码中调用的回调方法之间会遇到的延迟类型?

Boost是一个非常好的库,但非常通用,是否有较低的延迟替代?

非常欢迎所有关于编写低延迟UDP网络程序的意见。

编辑:另一个问题,是否有一种相对可行的方法来估计我在NIC和用户模式之间遇到的延迟?

2 个答案:

答案 0 :(得分:17)

您的延迟会有所不同,但它会远远超出您的最佳状态。以下几点可以阻止更好的延迟:

<强> Boost.Asio的

  1. 它不断分配/释放内存以存储“状态”,以便调用与您的读操作相关的回调函数。
  2. 为了支持异步和同步方法的混合,它进行了不必要的mutex锁定/解锁。
  3. 最糟糕的是,它会不断添加和删除基础通知机制中的事件描述符。
  4. 总而言之,asio对于高级应用程序开发人员来说是一个很好的库,但它带有很大的价格标签和大量的CPU周期。另一个替代方案是libevent,它好多了,但仍然旨在支持许多通知机制并且与平台无关。没有什么可以击败本机机制,即epoll

    其他事项

    1. UDP堆栈。它对延迟敏感的应用程序没有很好的作用。 OpenOnload是最受欢迎的解决方案之一。它绕过堆栈并直接与您的NIC一起工作。
    2. 调度。默认情况下,调度程序针对吞吐量而非延迟进行了优化。您将不得不调整和调整您的操作系统,以使其面向延迟。例如,Linux为此目的提供了许多“rt”补丁。
    3. 小心不要睡觉。一旦您的进程处于休眠状态,与持续刻录CPU并等待数据包到达相比,您将永远不会获得良好的唤醒延迟。
    4. 干扰其他IRQ,流程等。
    5. 我无法告诉您确切的数字,但假设您不会获得大量流量,使用Boost和常规Linux内核,使用常规硬件,您的延迟范围介于~50微秒到100毫秒之间。当你获得更多数据时,它会有所改善,并且在某些点开始下降后,它将始终是测距。我会说,如果你对这些数字没问题,不要打扰优化。

答案 1 :(得分:1)

我认为在“旋转”循环线程中使用recv()并将线程附加到单个CPU核心(Processor Affinity),延迟应该低于使用select(),select()的精度从1变化在我的测试中,旋转循环为1微秒,达到10微秒。