繁体   English   中英

使用sendfile而不是sendto的零拷贝udp套接字

[英]zero copy udp socket using sendfile instead of sendto

我正在实时环境中使用udp套接字。 我目前正在使用标准套接字函数sendto(),这需要花费大量时间。 我读到可以使用零拷贝,如果我理解得很好,可以避免通过从用户/内核环境复制文件来避免增加额外的时间。 但是,我看到sendfile()仅允许从一个文件描述符复制到另一个文件描述符。 我看不到如何使用它来发送UDP数据包,在我的情况下,这是一个缓冲区。 所以我的问题是:

  1. 甚至可以使用sendfile()发送UDP数据包吗?
  2. 如果是这样,正确的方法是什么?

编辑

我正在一个实时平台上工作,在该平台上我需要执行多项操作以及通过套接字进行发送。 所有这些都不应超过1ms。 我在三台机器上进行了尝试,第一台在3.4GHz时有4个内核,其他在2.3GHz时有8个内核,最后一个在1.4GHz时有4个内核。 在第一个上,发送720字节的数据包所需的时间少于1µs。 而另外两个则在6至9µs之间。 我使用的是Linux低延迟内核,并且停用了所有CPU电源管理功能,因此所有CPU均处于最大频率。

我注意到,如果sendto()花费的时间大于6µs,该平台将无法正常工作。 另一种精度是,我有多个并行运行的线程。 因此,也许只是CPU处理其他线程而sendto()尚未完成。 我想知道是否有可能在执行其他操作时停止sendto()。

这就是为什么我试图找到其他解决方案以在其他地方进行优化的原因,并且我认为使用sendfile()可以避免节省更多时间。

我不确定sendfile可以与UDP套接字一起使用,但是, memfd_create从内存创建文件描述符,并且理论上可以允许绕过从用户空间到内核的复制。

不过,在发送内核时,必须先将数据复制到内核套接字缓冲区中,因为它需要在用户数据之前添加UDP,IP和以太网标头,而这些标头不能就地完成。 即使使用sendfile也无法避免这种复制。

要进行真正的零拷贝联网,您可能想看看PF_RING ZC(零拷贝)驱动程序:

使用PF_RING感知驱动程序的按需内核绕过

PF_RING™ZC附带了新一代的PF_RING™感知驱动程序,可以在内核或旁路模式下使用。 安装后,驱动程序将作为标准Linux驱动程序运行,您可以在其中进行常规联网(例如ping或SSH)。 当从PF_RING™使用时,它们比普通驱动程序更快,因为它们直接与之交互。 如果使用零拷贝的支持PF_RING的驱动程序打开设备(例如pfcount -i zc:eth1),则该设备将无法通过标准网络使用,因为通过内核旁路以零拷贝访问该设备,就像以前的DNA一样。 一旦访问设备的应用程序关闭,标准的网络活动就可以再次发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM