2

这两种不同模型中的哪一种更有效(考虑抖动、处理器缓存的利用、整体设计、一切等)?

  1. 1 个 IOCP 和启动 X 个线程(其中 X 是计算机拥有的处理器数量)。这意味着我的“服务器”对于所有请求和 X 线程只有 1 个 IOCP(队列)来服务/处理它们。我已经阅读了许多讨论这种设计效率的文章。使用此模型,我将拥有 1 个也与 IOCP 关联的侦听器。让我们假设我可以弄清楚如何保持数据包/请求同步。

  2. X IOCP(其中 X 是计算机拥有的处理器数量)并且每个 IOCP 有 1 个线程。这意味着每个处理器都有自己的队列和 1 个线程来服务/处理它们。使用此模型,我将有一个单独的侦听器(不使用 IOCP)来处理传入连接并将 SOCKET 分配给正确的 IOCP(创建的 X 之一)。让我们假设我可以弄清楚负载平衡。

对两种设计(银行)使用过于简化的类比:

  1. 一条线有几个收银员来处理交易。每个人都在同一条线上,每个收银员都在排队等候下一个可用的人。

  2. 每个收银员都有自己的线路,人们被“放置”到其中一条线路中

在这两种设计之间,哪一种更高效。在每个模型中,重叠 I/O 结构将使用带有 MEM_COMMIT 的 VirtualAlloc(而不是“新”),因此交换文件不应成为问题(无分页)。根据向我描述的方式,将 VirtualAlloc 与 MEM_COMMIT 一起使用,内存被保留并且不会被分页。这将允许 SOCKETS 将传入数据直接写入我的缓冲区,而无需通过中间层。所以我不认为颠簸应该是一个因素,但我可能是错的。

有人告诉我 #2 会更有效率,但我没有听说过这个模型。提前感谢您的评论!

4

2 回答 2

2

我假设对于#2,您计划手动将您的套接字与您认为在接受套接字时基于某种“好”度量的“最佳”的 IOCP 关联?不知何故,这种“善良”的衡量标准会在插座的整个生命周期内持续存在?

使用 IOCP 使用“标准”方式,即您的选项编号 1,内核会计算出如何最好地使用您拥有的线程,并在其中任何一个阻塞时允许更多线程运行。使用您的方法,假设您以某种方式解决了如何分配工作,您最终将运行比选项 1 更多的线程。

您的 #2 选项还阻止您使用AcceptEx()重叠接受,这比使用普通接受循环更有效,因为您从场景中删除了一个线程(以及由此产生的上下文切换和潜在的争用)。

你的比喻不成立;实际上,更多的情况是,要么有 1 个队列,有 X 个银行柜员,你加入队列并知道你会以有效的顺序被看到,而不是每个柜员都有自己的队列,你不得不猜测你加入的队列不包含一大堆想要开设新账户的人,而您旁边的一个包含一大堆只想做一些支付的人。单一队列确保您得到有效处理。

我想你对MEM_COMMIT. 这并不意味着内存不在分页文件中并且不会被分页。使用重叠缓冲区的通常原因VirtualAlloc是确保页面边界对齐,从而减少为 I/O 锁定的页面数量(可以在页面边界上分配页面大小的缓冲区,因此只占用一页而不是发生跨越两个,因为内存管理器决定使用一个不在页面边界开始的块)。

总的来说,我认为您正在尝试提前优化某些东西。首先以正常方式使用 IOCP 获得高效的服务器,然后对其进行分析。我严重怀疑你甚至需要担心构建你的#2版本......同样,使用new分配你的缓冲区开始,然后切换到VirtualAlloc()当你发现你的服务器失败时增加的复杂性,ENOBUFS并且你请确定这是由 I/O 锁定页面限制引起的,而不是缺少非分页池(您确实意识到您必须为“分配粒度”大小的块分配VirtualAlloc()?)。

无论如何,我在这里有一个免费的 IOCP 服务器框架:http ://www.serverframework.com/products---the-free-framework.html ,它可能会帮助您入门。

已编辑:您建议的复杂版本在某些 NUMA 架构中可能很有用,在这些架构中,您使用 NIC 组合让交换机在多个 NIC 之间分配流量,将每个 NIC 绑定到不同的物理处理器,然后将 IOCP 线程绑定到同一个处理器。然后,您从该 NUMA 节点分配内存,并有效地让您的网络交换机对您的 NUMA 节点之间的连接进行负载平衡。恕我直言,我仍然建议最好获得一个工作服务器,您可以使用首先使用 IOCP 的“正常”方法进行分析,并且只有在您知道跨 NUMA 节点问题实际上会影响您的性能转向更复杂的情况时建筑学...

于 2011-02-12T16:55:26.367 回答
0

排队论告诉我们,单个队列比多个队列具有更好的特性。你可以通过偷工减料来解决这个问题。

多队列方法应该有更好的缓存行为。是否明显更好取决于有多少接收到的数据包与单个事务相关联。如果请求适合单个传入数据包,那么即使使用单个 IOCP 方法,它也会关联到单个线程。

于 2011-02-12T16:25:31.023 回答