我正在研究是否可以在 Windows 上实现 HPC 应用程序以高速率接收小型 UDP 多播数据报(大多为 100-400 字节),使用十几个或最多 200 个多播组(即使用 MSI-X 和 RSS,我可以扩展到多个核心),对每个数据包进行一些处理,然后将其发送出去。通过 TCP 发送,我设法达到了我需要的速度(6.4Gb/秒),没有遇到瓶颈,但以高 pps 速率接收数据报却成了问题。
在一个最近的测试在一台高规格的 NUMA 机器上,配有 2 端口 10Gb 以太网网卡,运行 Windows 2012 R2,我只能每秒接收数十万个 UDP 数据报(提前丢弃,即不实际处理数据,从等式中移除我的应用程序的处理开销,看看它有多快)使用 2x12 核心,测试的 12 个多播组的内核部分似乎分布在一个 NUMA 节点的 8 个或 10 个核心上(最大 RSS 队列设置为 16) - 尽管使用.net 应用程序,但本机应用程序应该能够运行得更快。
但即使伦·霍尔盖特 仅能以 500kpps 的速度接收 UDP 数据包在他的高性能 Windows RIO 测试,使用1024字节的UDP有效负载。
在QLogic 的白皮书(未提及测试中的操作系统)“多线程超小数据包路由”的限制(包括接收和后续发送?)设置为5.7Mpps。 在文章在Linux 网络,限制设定为1Mpps 至 2Mpps每个核心(据报道或多或少呈线性增长),甚至15Mpps采用绕过内核的特殊解决方案。
例如网络地图
可以以线速率生成流量(14.88Mpps) 在 10GigE 链路上,只有一个内核以 900Mhz 的速度运行。这相当于每个数据包大约 60-65 个时钟周期,并且可以很好地随内核和时钟频率扩展(使用 4 个内核,线路速率可达到低于 450 MHz)。接收端也达到了类似的速率。
那么我可以使用 (最新版本的) Windows/Windows Server 到什么程度,特别是接收前文所述的 UDP 多播?
编辑有一篇 cloudflare 博客文章 - 以及一个有趣的评论部分 - 介绍了如何在 Linux 上执行此操作:如何每秒接收一百万个数据包,还有相应的黑客新闻评论页面。
答案1
据微软称,他们在实验室进行的测试显示“在早期测试的特定服务器上”里约,他们能够处理
- 2Mpps 无损失在 Windows Server 2008R2 中,即没有 RIO
- 使用 RIO 在 Windows Server 8(预发布版)上实现 4Mpps
该视频截图(44:33):
所以我的问题的答案Is it possible to process millions of datagrams per second with Windows?
将会:是的,显然它甚至早于 RIO,在 Windows Server 2008R2 中。
但是除了官方数据(尤其是未发布软件的数据)之外,由于本次演示中仅提供了少量信息,因此关于测试以及如何正确解释结果仍存在许多问题。最相关的问题是:
- 这些数字是发送的吗? 接收的吗?或者也许用于路由(即接收+发送)?
- 数据包大小是多少?-> 可能是最低的,就像人们为了炫耀而试图获得 pps 数据时通常做的那样
- 有多少个连接(如果是 TCP)/数据包流(如果是 UDP)? -> 可能需要尽可能多的内核来分配工作负载,以便可以使用所有现有内核
- 什么测试设置?机器和 NIC 规格及接线
第一个至关重要,因为发送和接收需要不同的步骤,并且可能会显示出巨大的性能差异。对于其他数字,我们可以假设在高规格机器上使用最小数据包大小,每个核心至少有一个连接/数据包流,以获得最大可能的 Mpps 数字。
编辑我刚刚偶然发现了一份英特尔文件高性能数据包处理在 Linux 上,并且据此,(Linux)
平台可维持每秒约 200 万笔交易的交易率
使用标准 Linux 网络堆栈(在具有 2x8 核的物理主机上)。此请求/回复测试中的事务包括
- 接收 UDP 数据包
- 随后转发该数据包
(使用 netperf 的 netserver)。测试并行运行 100 个事务。对于那些感兴趣的人,论文中还有更多细节。我希望我们有类似的东西用于 Windows 比较...无论如何,这是该请求/回复测试最相关的图表:
答案2
总结
要给出一个明确的答案,似乎需要进行更多测试。但间接证据表明,Linux 是超低延迟社区中几乎唯一使用的操作系统,它也经常处理 Mpps 工作负载。这并不意味着 Windows 不可能做到这一点,但 Windows 可能会落后很多,即使它可能达到 Mpps 的数字。但这需要测试来确定,例如,找出以什么(CPU)成本可以实现这些数字。
注意:这不是我打算接受的答案。它旨在为任何对这个问题的答案感兴趣的人提供一些提示,让我们知道我们的立场以及需要进一步调查的地方。
Len Holgate,根据谷歌的说法,似乎是唯一一个测试过 RIO 以从 Windows 网络中获得更高性能的人(并发布了结果),刚刚在在他的博客上发表评论他使用单个 IP/端口组合来发送 UDP 数据包。
换句话说,他的结果应该与 Linux 上测试的单核数据有些相似(尽管他使用了 8 个线程 - 在没有检查他的代码的情况下,当只处理单个 UDP 数据包流并且不对数据包进行任何繁重的处理时,这似乎对性能有害,并且他提到实际上只使用了几个线程,这是有道理的)。尽管他说:
我并没有刻意去追求最大化的性能,只是为了比较新旧 API 之间的相对性能,所以我的测试并不那么彻底。
但什么是放弃标准 IOCP 的(相对)舒适区,进入更加粗糙的 RIO 世界除了“努力”之外,还有其他方法吗?至少就单个 UDP 数据包流而言。
我猜他的意思是——因为他在 RIO 的几次测试中尝试了各种设计方法——他没有微调 NIC 设置来榨干最后一点性能。例如,在接收缓冲区大小可能会对 UDP 接收性能和数据包丢失数据产生巨大的积极影响。
但是,当尝试直接将他的结果与其他 Linux/Unix/BSD 测试的结果进行比较时,问题在于:大多数测试在尝试突破“每秒数据包数”界限时,都使用尽可能小的数据包/帧大小,即 64 字节的以太网帧。Len 测试了 1024 字节数据包(-> 1070 字节帧),这(尤其是对于 No-Nagle UDP)可以为您带来更高的“每秒位数”数字,但可能无法像较小的数据包那样突破 pps 界限。因此,按原样比较这些数字是不公平的。
总结迄今为止我对 Windows UDP 接收性能的探索结果:
- 在尝试开发超低延迟和/或高吞吐量应用程序时,没有人真正使用 Windows,现在他们正在使用 Linux
- 如今,几乎所有具有实际结果的性能测试和报告(即不仅仅是产品广告)都是在 Linux 或 BSD 上进行的(感谢 Len 作为先驱者并为我们提供至少一个参考点!)
- Windows 上的 UDP(标准套接字)比 Linux 上的快还是慢?我还不能确定,必须自己测试一下
- Windows 上的高性能 UDP(RIO 与 netmap)比 Linux 上更快/更慢吗?Linux容易地以 900MHz 的单核速度处理完整的 10Gb 线路速度,Windows,最佳案例发表对于 1024 的大型 UDP 数据包,能够上升到 43% 或 492kpps,也就是说,较小尺寸的 bps 数字可能会明显变差,尽管 pps 数字可能会上升(除非中断处理或其他内核空间开销是限制因素)。
至于他们为什么使用 Linux,那一定是因为开发涉及内核更改(如 netmap 或 RIO)的解决方案(在将性能推向极限时必不可少)在 Windows 这样的封闭系统中几乎是不可能的,除非你的薪水恰好来自雷德蒙德,或者你与微软签订了特殊合同。这就是为什么 RIO 是 MS 产品的原因。
最后,仅举几个我发现的 Linux 领域过去和现在正在发生的极端例子:
早在 15 年前,有些人就使用800 mHz 奔腾 III CPU,133 mHz 前端总线在 1GbE NIC 上。 编辑:他们使用点击,一个内核模式路由器,绕过了大部分标准网络堆栈,也就是说,他们“作弊了”。
2013年,Argon Design管理要得到
交易延迟低至 35ns [纳秒]
顺便说一句,他们还声称
和 Argon 使用Arista 7124FX 交换机,(除了 FPGA 之外)还具有操作系统
建立在标准 Linux 内核之上。