5

This is just a general question relating to some high-performance computing I've been wondering about. A certain low-latency messaging vendor speaks in its supporting documentation about using raw sockets to transfer the data directly from the network device to the user application and in so doing it speaks about reducing the messaging latency even further than it does anyway (in other admittedly carefully thought-out design decisions).

My question is therefore to those that grok the networking stacks on Unix or Unix-like systems. How much difference are they likely to be able to realise using this method? Feel free to answer in terms of memory copies, numbers of whales rescued or areas the size of Wales ;)

私が理解しているように、彼らのメッセージングは​​UDPベースであるため、TCP接続の確立などに問題はありません。

幸運をお祈りしています、

マイク

4

2 に答える 2

1

http://vger.kernel.org/~davem/tcp_output.html Google で検索するとtcp_transmit_skb()、tcp データパスの重要な部分である画像がいくつかあります。彼のサイトhttp://vger.kernel.org/~davem/にはもっと興味深いものがあります

user - tcp datapath の送信部分には、user から skb への1 つのコピーskb_copy_to_page( による送信時tcp_sendmsg()) と0 のコピーdo_tcp_sendpages( による呼び出し) がありtcp_sendpage()ます。未配信セグメントの場合に備えて、データのバックアップを保持するためにコピーが必要です。カーネル内の skb バッファーは複製できますが、それらのデータは最初の (元の) skb に残ります。Sendpage は、他のカーネル部分からページを取得し、バックアップ用に保持できます (COW のようなものがあると思います)。

パスを呼び出します (lxr から手動で)。送信tcp_push_one/__tcp_push_pending_frames

tcp_sendmsg() <-  sock_sendmsg <- sock_readv_writev <- sock_writev <- do_readv_writev

tcp_sendpage() <- file_send_actor <- do_sendfile 

受け取るtcp_recv_skb()

tcp_recvmsg() <-  sock_recvmsg <- sock_readv_writev <- sock_readv <- do_readv_writev

tcp_read_sock() <- ... spliceread for new kernels.. smth sendfile for older

受信では、カーネルからユーザー(から呼び出される) への1 つのコピーが存在する可能性があります。そして tcp_read_sock() にはコピーがあります。コールバック関数を呼び出します。ファイルまたはメモリに対応する場合、DMA ゾーンからデータをコピーする場合とコピーしない場合があります。他のネットワークの場合、受信パケットの skb があり、そのデータをその場で再利用できます。skb_copy_datagram_iovectcp_recvmsgsk_read_actor

udp の場合 - 受信 = 1 コピー -- udp_recvmsg から呼び出された skb_copy_datagram_iovec。送信 = 1 コピー-- udp_sendmsg -> ip_append_data -> getfrag (ユーザーからの 1 コピーの ip_generic_getfrag のようですが、ページ コピーのない sendpage/splice のようなものかもしれません。)

一般的に言えば、ユーザー空間との間で送受信する場合は少なくとも 1 つのコピーが必要であり、データのカーネル空間ソース/ターゲット バッファーでゼロコピー (驚き!) を使用する場合は 0 コピーが必要です。パケットを移動せずにすべてのヘッダーが追加され、DMA 対応の (すべて最新の) ネットワーク カードは、DMA 対応のアドレス空間の任意の場所からデータを取得します。古いカードの場合、PIO が必要なので、カーネル空間から PCI/ISA/smthese I/O レジスタ/メモリまで、もう 1 つのコピーがあります。

UPD: NIC (ただし、これは nic に依存しますが、8139too をチェックしました) から tcp スタックへのパスには、もう 1 つのコピーがあります: rx_ring から skb へ、受信の場合も同じです: skb から tx buffer +1copy へ。ip および tcp ヘッダーを入力する必要がありますが、skb にはそれらが含まれているか、または配置されていますか?

于 2010-04-22T02:50:15.723 に答える
1

高パフォーマンスでレイテンシを削減するには、カーネル ドライバーの使用を拒否する必要があります。ユーザー空間ドライバーを使用すると、最小のレイテンシーが実現されます (MX はそれを行いますが、Infinband も可能性があります)。

Linux ネットワークの内部構造については、かなり適切な (しかし少し古い) 概要 "A Map of the Networking Code in Linux Kernel 2.4.20" があります。TCP/UDP データパスにはいくつかのスキームがあります。

raw ソケットを使用すると、tcp パケットのパスが少し短くなります (アイデアをありがとう)。カーネルの TCP コードはレイテンシを追加しません。ただし、ユーザーはすべての tcp プロトコル自体を処理する必要があります。いくつかの特定の状況に合わせて最適化する可能性があります。クラスターのコードは、デフォルトの TCP/UDP スタックのように、長距離リンクまたは低速リンクの処理を必要としません。

私もこのテーマにとても興味があります。

于 2010-04-22T00:05:49.900 に答える