我正在重新编写现有应用程序中的一些基础结构,这些应用程序将UDP数据包发送到1 ... N个地址(通常是多播)。目前,有T发射机对象,在某些情况下,所有发射机都发送到同一地址。
因此,为了简化并提供一个示例案例,假设有3个发送器对象,它们都需要发送到单个特定地址。我的问题是......哪个更有效率?:
选项1)在单个套接字周围放置一个互斥锁,让所有发送器(T)共享同一个套接字。
T----\
T----->Socket
T----/
选项2)使用三个独立的套接字,所有套接字都发送到同一位置。
T----->Socket 1
T----->Socket 2
T----->Socket 3
我怀疑使用第二个选项,操作系统或网卡会在最终传输周围放置一个互斥锁,所以在大图中,选项2可能与选项1不同。
下周我可能会在我的开发PC上设置一个实验,但是我无法测试用户可能安装的所有潜在计算机配置。我也意识到有不同的实现 - Windows vs Linux,不同的NIC芯片组制造商等,但我想知道是否有人可能有一些过去的经验或架构知识可以揭示一个选项优于另一个选项的优势。
谢谢!
答案 0 :(得分:1)
在Windows 10计算机上运行一些基准测试后,我得到一个“答案”,至少让我大致了解了会发生什么。我无法100%确定每个系统的行为方式都相同,但我运行的大多数服务器都使用Intel NIC和Windows 10,而我的典型数据包大小约为1200字节,所以答案至少让我觉得舒服这对我的特定情况是正确的。我决定在此发布结果,以防其他任何人可以使用该实验。
我构建了一个简单的命令行应用程序,它首先使用带有互斥锁的单个插槽生成T个发送器线程。紧接着之后,它将使用相同数量的发射器运行另一个测试,但这次每个发射器都有自己的插座,因此不需要互斥锁(虽然我确定在较低级别有一个锁定机制)。每个发射机都尽可能快地发送数据包。
这是我使用的测试设置:
以下是结果
正如预期的那样,只有一个线程的测试两者的时间几乎相同。但是,在具有3,6和12个发送器的情况下,通过每个线程使用一个插槽而不是共享插座,性能提升约3%。这并不是一个巨大的差异,但如果你试图从系统中挤出最后一盎司,这可能是一个有用的统计数据。我的特定应用是传输大量视频。
正如完整性检查....这是服务器端TaskManager网络页面的屏幕截图。您可以在测试的一半时看到吞吐量增加,这与切换到第二个多插槽测试一致。我还包括客户端计算机的屏幕截图(它是一个Windows 7盒子)。