C++ UDP端口的低延迟读取
我正在从UDP端口读取单个数据项。此读取必须尽可能降低延迟。目前,我正在通过boost::asio库的C++ UDP端口的低延迟读取,c++,boost,boost-asio,latency,C++,Boost,Boost Asio,Latency,我正在从UDP端口读取单个数据项。此读取必须尽可能降低延迟。目前,我正在通过boost::asio库的async\u receive\u from方法进行阅读。有人知道在数据包到达网卡和在我的用户代码中调用回调方法之间我会经历什么样的延迟吗 Boost是一个非常好的库,但非常通用,是否有更低延迟的替代方案 所有关于编写低延迟UDP网络程序的意见都是非常受欢迎的 编辑:另一个问题,是否有一种相对可行的方法来估计我在NIC和用户模式之间所经历的延迟?您的延迟会有所不同,但远不是您所能得到的最佳延迟。
async\u receive\u from
方法进行阅读。有人知道在数据包到达网卡和在我的用户代码中调用回调方法之间我会经历什么样的延迟吗
Boost是一个非常好的库,但非常通用,是否有更低延迟的替代方案
所有关于编写低延迟UDP网络程序的意见都是非常受欢迎的
编辑:另一个问题,是否有一种相对可行的方法来估计我在NIC和用户模式之间所经历的延迟?您的延迟会有所不同,但远不是您所能得到的最佳延迟。以下几点将阻碍您实现更好的延迟: Boost.ASIO
mutex
锁定/解锁,以支持异步和同步方法的混合asio
对于高级应用程序开发人员来说是一个很好的库,但是它有一个巨大的价格标签和大量消耗CPU周期的小精灵。另一种选择是libevent
,它要好得多,但仍然旨在支持许多通知机制,并且独立于平台。没有什么能打败本机机制,即epoll
其他事项
我无法告诉您确切的数字,但假设使用Boost和常规Linux内核,并使用常规硬件,您不会获得大量流量,那么您的延迟将在约50微秒到约100毫秒之间。当你获得更多的数据时,它会有一点改进,在某个点开始下降后,它会一直在变化。我想说,如果您对这些数字没有意见,就不用麻烦优化了。我认为在“旋转”循环线程中使用recv()并将线程连接到单个CPU核心(处理器亲缘关系),延迟应该比使用select()低,select()的精度从1到10微秒不等,而在我的测试中旋转循环为1微秒。这些都是非常好的信息,非常感谢。流量可以忽略不计,我可能会收到1-2个30-50字节的数据包,在整个过程中都是如此,所以我是一个非常棘手的问题。我目前使用的是Windows,但似乎我们应该在短期内转向Linux,我将调查您提到的RT修补程序。@endian:不客气。Linux可能会做得更好。我从来没有听说过Windows做低延迟的工作。此外,请确保首先优化硬件。获得Solarflare NIC和高端服务器要比优化代码便宜得多,只有在达到合理的硬件开销限制时才能改进代码。UDT()可能值得一看,尽管它在吞吐量方面得到了优化。但作为一个比较,它可能会很有趣……只是补充一下Vlad的答案:如果没有硬件加速,你最好的选择可能是在非阻塞UDP套接字上使用普通的
recv()
。只是添加一个数据点,我发现使用boost:的延迟要低得多:大约10个麦克风,包括我的数据包处理代码。不过,我使用的是64位linux,使用的是非常高端的服务器。不过,我得到了很大的延迟峰值,更令人担忧的是,UDP缓冲区溢出。我觉得native epoll会让事情变得更加清晰。@javapowered在各自的手册页中是否有未包含的内容?还有?@sehe我想我现在应该改变我的问题:)我决定使用普通的阻塞recvmsg
,因为在“一个线程一个套接字”配置中它很容易而且可能不坏。公认的答案建议使用epoll
(适用于多个套接字,但我们是否应该将其用于单个套接字?)。与“recvmsg一个线程一个套接字”相比,它实际上会更好吗?recvmsg
阻塞有那么糟糕吗?@javapowered这都是关于选择的。它在实际资源上阻塞的事实可能会给它提供最低的延迟。但公认的答案确实包含了大量关于如何从操作系统中挤出最后一滴响应度的相关信息