たとえば、TCP/IP (POSIX poll/select またはより高度な epoll、kqueue、poll_set、IOCP を使用) を使用した非同期 IO の場合、ネットワーク ドライバーは、異なる (ハードウェア デマルチプレクサ) CPU コアの割り込みによって開始され、メッセージとダンプを受信します。それらをカーネルレベルで単一の(マルチプレクサー)バッファーに入れます。次に、epoll / kqueue / poll_set / IOCP を使用したスレッドアクセプターは、この単一のバッファーからメッセージのソケットの記述子のリストを受信し、異なる CPU コアで実行されている (スレッドプール内の) スレッド全体に分散 (デマルチプレクサー) します。 .
要するに、スキームは次のようになります: ハードウェアの中断 (ハードウェア デマルチプレクサ) -> カーネル空間のネットワーク ドライバ (マルチプレクサ) -> epoll / kqueue / poll_set / IOCP を使用したユーザー空間のユーザーのアクセプタ (デマルチプレクサ)
最後の 2 つのリンクを取り除き、「ハードウェア デマルチプレクサ」のみを使用する方が簡単で高速ではありませんか?
例。ネットワーク パケットが到着すると、ネットワーク カードは CPU に割り込みます。今日のほとんどのシステムでは、これらの割り込みはコア全体に分散されています。つまり、この作品はハードウェア デマルチプレクサです。このような割り込みを受け取った後、すぐにこのネットワークのメッセージを処理し、次の割り込みを待つことができます。デマルチプレックスのすべての作業は、CPU 割り込みを使用して、ハードウェアのレベルで行われます。
Cortex-A5 MPCore: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0434b/CCHDBEBE.html
QNXなどのリアルタイム* nixで、すべてのLinuxでアプローチが実行可能ですか?このアプローチが使用されているパブリックプロジェクトはngnixの可能性がありますか?
アップデート:
私の質問に対する簡単な答え -はい、次を使用してハードウェア逆多重化を使用できます/proc/irq/<N>/smp_affinity
: http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux
しかし、2 つ目の注意点として、1 つのパケットの異なる部分が異なるコアで処理される可能性があり、キャッシュの一貫性のために同期 (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 なし) を使用する例など、より良い解決策があるのでしょうか?