1

例如,对于使用 TCP/IP(使用 POSIX poll/select 或更高级的 epoll、kqueue、poll_set、IOCP)的异步 IO,网络驱动程序通过不同(硬件解复用器)CPU 内核中的中断启动,接收消息并转储将它们放入内核级别的单个(多路复用器)缓冲区中。然后,我们的线程接受器通过使用 epoll / kqueue / poll_set / IOCP 从这个单一缓冲区接收消息的套接字描述符列表,这些消息在不同 CPU 内核上运行的线程(在线程池中)再次分散(解复用器) .

简而言之,方案看起来像:硬件中断(硬件解复用器)-> 内核空间中的网络驱动程序(多路复用器)-> 用户空间中的用户接受器,使用 epoll/kqueue/poll_set/IOCP(解复用器

摆脱最后两个环节,只使用“硬件解复用器”不是更容易、更快捷吗?

一个例子。如果有网络包到达,网卡就会中断CPU。在当今的大多数系统上,这些中断分布在内核之间。即这项工作是一个硬件解复用器。收到这样的中断后,我们可以立即处理这个网络的消息,等待下一次中断。通过使用 CPU 中断,所有用于解复用的工作都在硬件级别完成。

在 Cortex-A5 MPCore 中: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0434b/ CCHDBEBE.html

在所有 Linux 中,实时 *nix(如 QNX)中的方法是否可行,是否有使用这种方法的公共项目,可能是 ngnix?

更新:

对我的问题的简单回答 -是的,我可以通过以下方式使用硬件解复/proc/irq/<N>/smp_affinityhttp ://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux

但第二个注意事项 - 这不是一件好事,因为一个数据包的不同部分可以由不同的内核处理,并且缓存同步(L1(CoreX)->L3->L1(CoreY))可能需要时间来实现缓存一致性:http ://www.alexonlinux.com/why-interrupt-affinity-with-multiple-cores-is-not-such-a-good-thing

解决方案:

  • 将不同的以太网适配器(其 IRQ)硬绑定到不同的单个 CPU 内核
  • 使用大数据包和小消息,当数据包通常包含完整的消息时

问题:但是可能有一些更好的解决方案,当我们手动从网络适配器接收一批网络数据包时使用软IRQ(没有硬件IRQ)的例子,有吗?

4

2 回答 2

2

你问了一个相当广泛的问题。

...摆脱最后两个链接,只使用“硬件解复用器”?

根据您的描述,我了解到您真正想要的是硬件将接收到的数据提供给用户的应用程序。不是吗?这可以通过RDMA来实现。

硬件(网卡)可以在预先分配的缓冲区中提供接收到的数据,而无需 CPU 参与此过程。

我可以详细说明,但我不确定这个方向是你要问的。

于 2013-08-26T21:49:57.320 回答
2

对我的问题的简单回答 -是的,我可以通过以下方式使用硬件解复/proc/irq/<N>/smp_affinityhttp ://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux

但第二个注意事项 - 这不是一件好事,因为一个数据包的不同部分可以由不同的内核处理,并且缓存同步(L1(CoreX)->L3->L1(CoreY))可能需要时间来实现缓存一致性:http ://www.alexonlinux.com/why-interrupt-affinity-with-multiple-cores-is-not-such-a-good-thing

解决方案:

  • 将不同的以太网适配器(其 IRQ)硬绑定到不同的单个 CPU 内核
  • 使用大数据包和小消息,当数据包通常包含完整的消息时
于 2013-08-30T08:31:58.737 回答