我正在从UDP端口读取单个数据项.这次读取必须尽可能地降低延迟.目前我正在通过boost :: asio库的async_receive_from
方法阅读.有谁知道我到达网卡的数据包与我的用户代码中调用的回调方法之间会遇到的延迟类型?
Boost是一个非常好的库,但非常通用,是否有更低的延迟替代?
所有关于编写低延迟UDP网络程序的意见都非常受欢迎.
编辑:另一个问题,是否有一种相对可行的方法来估计我在NIC和用户模式之间遇到的延迟?
您的延迟会有所不同,但远不是您能获得的最佳效果.以下是一些可以阻止更好延迟的事情:
Boost.Asio的
它不断地分配/释放内存来存储"状态",以便调用与您的读操作相关的回调函数.
它执行不必要的mutex
锁定/解锁,以支持异步和同步方法的混乱.
最糟糕的是,它不断地从底层通知机制中添加和删除事件描述符.
总而言之,asio
对于高级应用程序开发人员来说,它是一个很好的库,但它带有很大的价格标签和大量的CPU周期.另一种选择是libevent
,它好多了,但仍然旨在支持许多通知机制并且与平台无关.什么都不能击败本机机制,即epoll
.
其他事情
UDP堆栈.它对延迟敏感的应用程序没有很好的作用.OpenOnload是最受欢迎的解决方案之一.它绕过堆栈并直接与您的NIC一起工作.
调度.默认情况下,调度程序针对吞吐量而非延迟进行了优化.您将不得不调整和调整您的操作系统,以使其面向延迟.例如,Linux为此目的提供了许多"rt"补丁.
小心不要睡觉.一旦您的进程处于休眠状态,与持续刻录CPU和等待数据包到达相比,您将永远不会获得良好的唤醒延迟.
干扰其他IRQ,流程等
我无法告诉您确切的数字,但假设您不会获得大量流量,使用Boost和常规Linux内核,使用常规硬件,您的延迟将介于约50微秒到约100毫秒之间.当你获得更多数据时,它会有所改善,并且在某些点开始下降后,它将始终是测距.我会说,如果你对这些数字没问题,不要费心去优化.