最大化 udp 性能
我正在开发一个有两个客户端的项目,一个用于发送,另一个用于接收 udp 数据报,两台机器之间直接相互连接。 每个数据报大小为1024byte,使用winsock(阻塞)发送。 它们都在非常快的机器上运行(单独的)。配备 16GB RAM 和 8 个 CPU,配备 raid 0 驱动器。
我正在寻找最大化我的吞吐量的技巧,技巧应该是winsock级别的,但如果你有其他一些技巧,那就太好了。
目前我的传输速度为 250-400mbit。我正在寻找更多。
谢谢。
im working on a project with two clients ,one for sending, and the other one for receiving udp datagrams, between 2 machines wired directly to each other.
each datagram is 1024byte in size, and it is sent using winsock(blocking).
they are both running on a very fast machines(separate). with 16gb ram and 8 cpu's, with raid 0 drives.
im looking for tips to maximize my throughput , tips should be at winsock level, but if u have some other tips, it would be great also.
currently im getting 250-400mbit transfer speed. im looking for more.
thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
由于我不知道您的应用程序除了发送和接收之外还执行什么操作,因此很难知道还有什么可能限制它,但这里有一些可以尝试的事情。我假设您使用的是 IPv4,而我不是 Windows 程序员。
当您使用可靠的连接时,最大化您发送的数据包大小。对于 100 mbs 以太网,最大数据包为 1518 个,以太网使用其中的 18 个,IPv4 使用 20-64 个(通常认为是 20 个),UDP 使用 8 个字节。这意味着通常您应该能够发送每个数据包 1472 字节的 UDP 有效负载。
如果您使用支持它的千兆位以太网设备,您的数据包大小会增加到 9000 字节(巨型帧),因此发送接近该大小的数据应该会加快速度。
如果您要从侦听器向发送器发送任何确认,请尝试确保它们很少发送,并且一次可以确认多个数据包。尽量让听者不必说太多,并尽量让发送者不必等待听者允许继续发送。
在发送方应用程序所在的计算机上,考虑为接收方所在的计算机设置静态 ARP 条目。如果没有此功能,每隔几秒可能会暂停一次,同时发出新的 ARP 请求以确保 ARP 缓存是最新的。某些 ARP 实现可能会在 ARP 条目过期之前很好地执行此请求,这会减少影响,但有些则不会。
关闭尽可能多的网络用户。如果您使用的是以太网交换机,那么您应该专注于那些会向/来自您的应用程序驻留/使用的计算机/网络设备引入流量的事情(这包括广播消息,如许多 ARP 请求)。如果它是一个集线器,那么您可能需要让整个网络安静下来。 Windows 往往会向网络发送源源不断的垃圾流,这在许多情况下是没有用的。
一个应用程序或用户可以拥有的网络带宽可能受到限制。或者操作系统允许其自行使用的网络带宽可能会受到限制。如果存在的话,可以在注册表中更改它们。
网络接口芯片实际上始终不支持网络的最大带宽的情况并不罕见。有些芯片可能会丢失数据包,因为它们正忙于处理先前的数据包,而有些芯片则无法像以太网规范所允许的那样紧密地发送数据包。此外,即使是这样,系统的其余部分也可能无法跟上。
Since I don't know what else besides sending and receiving that your applications do it's difficult to know what else might be limiting it, but here's a few things to try. I'm assuming that you're using IPv4, and I'm not a Windows programmer.
Maximize the packet size that you are sending when you are using a reliable connection. For 100 mbs Ethernet the maximum packet is 1518, Ethernet uses 18 of that, IPv4 uses 20-64 (usually 20, thought), and UDP uses 8 bytes. That means that typically you should be able to send 1472 bytes of UDP payload per packet.
If you are using gigabit Ethernet equiptment that supports it your packet size increases to 9000 bytes (jumbo frames), so sending something closer to that size should speed things up.
If you are sending any acknowledgments from your listener to your sender then try to make sure that they are sent rarely and can acknowledge more than just one packet at a time. Try to keep the listener from having to say much, and try to keep the sender from having to wait on the listener for permission to keep sending.
On the computer that the sender application lives on consider setting up a static ARP entry for the computer that the receiver lives on. Without this every few seconds there may be a pause while a new ARP request is made to make sure that the ARP cache is up to date. Some ARP implementations may do this request well before the ARP entry expires, which would decrease the impact, but some do not.
Turn off as many users of the network as possible. If you are using an Ethernet switch then you should concentrate on the things that will introduce traffic to/from the computers/network devices on which your applications are running reside/use (this includes broadcast messages, like many ARP requests). If it's a hub then you may want to quiet down the entire network. Windows tends to send out a constant stream of junk to networks which in many cases isn't useful.
There may be limits set on how much of the network bandwidth that one application or user can have. Or there may be limits on how much network bandwidth the OS will let it self use. These can probably be changed in the registry if they exist.
It is not uncommon for network interface chips to not actually support the maximum bandwidth of the network all the time. There are chips which may miss packets because they are busy handling a previous packet as well as some which just can't send packets as close together as Ethernet specifications would allow. Additionally the rest of the system might not be able to keep up even if it is.
需要注意的一些事项:
SO_SNDBUF
和SO_RCVBUF
套接字选项来平衡尖峰和数据包丢失Some things to look at:
SO_SNDBUF
andSO_RCVBUF
socket options to balance out spikes and packet drop使用 1Gbps 网络并升级您的网络硬件...
use 1Gbps network and upgrade your network hardware...
使用经过验证的代码(例如 iperf)测试硬件的数据包限制:
http:// /www.noc.ucf.edu/Tools/Iperf/
我正在链接 Windows 版本,启动 Linux LiveCD 并尝试 Linux 版本来比较 IP 堆栈可能是个好主意。
您的网卡更有可能性能不佳,请尝试使用英特尔千兆位服务器适配器:
http ://www.intel.com/network/connectivity/products/server_adapters.htm
Test the packet limit of your hardware with an already proven piece of code such as iperf:
http://www.noc.ucf.edu/Tools/Iperf/
I'm linking a Windows build, it might be a good idea to boot off a Linux LiveCD and try a Linux build for comparison of IP stacks.
More likely your NIC isn't performing well, try an Intel Gigabit Server Adapter:
http://www.intel.com/network/connectivity/products/server_adapters.htm
对于 TCP 连接,事实证明,使用多个并行连接可以更好地利用数据连接。我不确定这是否适用于 UDP,但它可能有助于解决数据包处理的一些延迟问题。
所以你可能想尝试多线程的阻塞调用。
For TCP connections it has been shown that using multiple parallel connections will better utilize the data connection. I'm not sure if that applies to UDP, but it might help with some of the latency issues of packet processing.
So you might want to try multiple threads of blocking calls.
除了 Nikolai 对发送和接收缓冲区的建议之外,如果可以的话,切换到重叠 I/O 并让许多接收待处理,这也有助于最大限度地减少由于缺乏缓冲区空间而被堆栈丢弃的数据报数量。
如果您正在寻找可靠的数据传输,请考虑UDT。
As well as Nikolai's suggestion of send and recv buffers, if you can, switch to overlapped I/O and have many recvs pending, this also helps to minimise the number of datagrams that are dropped by the stack due to lack of buffer space.
If you're looking for reliable data transfer, consider UDT.