跨网络发送数据的最快的C/C++技术

Fastest C/C++ technique for sending data across network?

本文关键字:C++ 技术 数据 网络      更新时间:2023-10-16

如果我有两个Linux盒子,并且我正在编写一个C/C++程序,在一个盒子上发送消息,在另一个盒子里接收消息,那么最快的方法是什么?

我不确定我听到的各种套接字/网络技术是否只是底层技术的包装,或者它们是否是替代的可能性。我只想知道什么最接近"裸金属",我可以从我的应用程序中实现它。

我认为最快的方法是将我的程序作为驱动程序编写,并将其加载到内核中。然而,我仍然需要知道与这个想法一起使用的最快的套接字实现。

任何现代PC都能够保持以太网芯片缓冲区的满负荷,因此"裸金属"编程不会带来任何好处。与网络延迟(即光速限制)相比,内核增加的延迟非常小,因此不值得优化。

对于在两个连接的Linux机箱之间"快速"移动的高带宽数据,TCP是您的朋友,因为它将优化自己以达到最大的网络能力,而无需检测和调整自己。直接连接将具有可忽略不计的数据包丢失和通常较低的延迟,因此您不必担心窗口大小等问题。

如果您想要"快速",比如快速处理小请求,请使用UDP。

如果你对"快"有其他定义,那么,你需要详细说明。

这个问题是不完整的,因为除了必须快速之外,您没有指定任何要求。这里有很多方面需要考虑,比如要使用的协议(TCP用于可靠性,UDP用于流式传输,等等)、序列化(你计划通过网络发送什么样的数据,你能使用像Google Protobuf这样的序列化库吗?)等等

我的建议是查看各种RPC框架,如Apache Thrift、Apace Etch或ZeroC Ice,并对它们进行基准测试,然后再决定是否真正需要使用BSD套接字API或类似的低级别抽象。

除非您想构建一个内核模块用于通过以太网进行自定义通信,否则libc中最快的用户空间API是Berkley Sockets API。是的,这是TCP/IP和UDP/IP内核的包装,这是一个IP之上的层,这是WWAN、LAN和以太网的层,它是其他层的层,但除非你需要如此令人难以置信和精确的性能,否则我建议你留在userland中的简单东西,而不是编写你需要使用的更低的内核模块。除非我完全错了,否则无法从用户空间访问原始以太网、WWAN或LAN,更不用说实际访问硬件了。

注意:如果您有几年的时间来重写整个UNIX网络堆栈和网卡驱动程序,那么在使用ioperm()调用以root用户身份运行时,您可以从用户空间获得x86 I/O端口访问权限,但我不建议重写整个UNIX网络堆栈。这几乎是20年的工作。此外,从三维应用程序直接访问硬件是一场即将发生的安全灾难。

注意:如果你不使用任何传统的硬件进行联网,你可以为双端USB电缆编写一个自定义驱动程序,并在此基础上创建一个自定义网络协议,因为编写Linux USB设备驱动程序可能是最容易编写的驱动程序,因为它有一个大型的API。不过,我真的不知道这里的速度如何,由于USb 2.0比旧的以太网标准更快,但后来它们开始有1Gbps的以太网,现在有了SUB 3.0,所以这可能更快或更慢,这取决于可用的硬件。这更多的是关于易用性。

编辑:为了速度,请永远不要把代码放在内核中。请你在机器上设置的巨大安全漏洞不值得在性能上得到小小的提升。曾经有一段时间,系统调用非常昂贵,您希望最小化并添加到内核是一种选择,但对于英特尔的sysenter/sysexit和AMD的syscall/sysret等较新标准,它们足够便宜,不足以保证存在安全漏洞。