例如,对于使用 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_affinity
:http ://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)的例子,有吗?