套接字服务器的高效重叠I / O.

时间:2011-02-12 15:36:42

标签: windows sockets visual-c++ performance io-completion-ports

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

  1. 1 IOCP并旋转X个线程(其中X是计算机具有的处理器数)。这意味着我的“服务器”只有1个IOCP(队列)用于所有请求,X线程用于服务/处理它们。我读过很多文章讨论这种设计的有效性。使用这个模型,我将有一个也将与IOCP相关联的监听器。让我们假设我可以弄清楚如何保持数据包/请求同步。

  2. X IOCP(其中X是计算机具有的处理器数),每个IOCP有1个线程。这意味着每个处理器都有自己的队列和1个线程来提供/处理它们。使用这个模型,我将有一个单独的监听器(不使用IOCP)来处理接收连接,并将SOCKET分配给正确的IOCP(已创建的X之一)。让我们假设我可以找出负载平衡。

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

    1. 一条线路上有几个收银员交易。每个人都在同一条线上,每个收银员都会排队等候下一个人。

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

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

      有人告诉我#2会更有效但我还没有听说过这种模式。提前感谢您的意见!

2 个答案:

答案 0 :(得分:2)

我认为对于#2,您打算手动将套接字与IOCP相关联,根据接受套接字时的“良好”度量,您认为该套件是“最佳”的?而这种“善意”的衡量标准将持续存在于套接字的生命中吗?

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

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

你的比喻崩溃了;实际上更多的情况是要么有一个队列与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绑定到不同的物理处理器,然后将您的IOCP线程绑定到同一个处理器。然后,您可以从该NUMA节点分配内存,并有效地让您的网络交换机负载平衡NUMA节点之间的连接。我仍然建议你更好地使用一个工作服务器,你可以使用“正常”方法使用IOCP进行分析,只有当你知道交叉NUMA节点问题实际上正在影响你的性能向更复杂的方向发展时架构...

答案 1 :(得分:0)

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

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

相关问题