1

プロトコルのスタックと、各レイヤーでの送信をきちんとカバーするいくつかの c/cpp コードを持つイメージング。各送信関数は、下のレイヤーを使用して別のヘッダーを追加し、最終的にメッセージ全体がレイヤー 0 の連続グローバル バッファーに配置されるようにします。

void SendLayer2(void * payload, unsigned int payload_length)
{
  Layer2Header header;   /* eat some stack */
  const int msg_length = sizeof(header) + payload_length;

  char msg[msg_length];  /* and have some more */
  memset(msg, 0, sizeof(msg));

  header.whatever = 42;
  memcpy(&buffer[sizeof(header)], payload, payload_length);

  SendLayer1(buffer, msg_length);
}

void SendLayer1(void * payload, unsigned int payload_length)
{
  Layer1Header header;   /* eat some stack */
  const int msg_length = sizeof(header) + payload_length;

  char msg[msg_length];  /* and have some more */
  memset(msg, 0, sizeof(msg));

  header.whatever = 42;
  memcpy(&buffer[sizeof(header)], payload, payload_length);

  SendLayer0(buffer, msg_length);
}

データはいくつかのグローバル変数に移動され、実際に転送されます。

char globalSendBuffer[MAX_MSG_SIZE];
void SendLayer0(void * payload, unsigned int payload_length)
{
  // Some clever locking for the global buffer goes here

  memcpy(globalSendBuffer, payload, payload_length);
  SendDataViaCopper(globalSendBuffer, payload_length);
}

このコードでスタックの使用量と memcpy() の数の両方を減らしたいので、次のようなものを想像します。

void SendLayer2(void * payload, unsigned int payload_length)
{            
  Layer2Header * header = GetHeader2Pointer();
  header->whatever = 42;

  void * buffer = GetPayload2Pointer();
  memcpy(buffer, payload, payload_length);

  ...
}

私の考えは、MAX_MSG_SIZE から継続的に減算し、上位層のコードに最後/右から直接グローバル バッファーを入力させることによって、各層ヘッダーの適切なオフセットと実際のペイロードのオフセットを計算する何かを下部に配置することです。側。

これは理にかなっていますか?代替の、おそらくよりエレガントなアプローチはありますか?

4

2 に答える 2

2

この記事に興味があるかもしれません: Alan Cox による「Network Buffers and Memory Management」 。基本的に、バッファと、そのバッファのさまざまな興味深い部分へのいくつかのポインタがあります: プロトコル ヘッダー、データなどバッファの先頭に近い。

BSD の mbuf についても、どこかに同様の記述があるはずです。

編集:

David Miller (Linux ネットワーキングのメンテナー) に記事「How SKBs work」があります。

于 2010-07-21T19:54:07.523 に答える
0

これは「ゼロコピー」のように聞こえます。私は専門家ではないので、その用語を検索すると、あらゆる種類の参考文献が見つかります。

于 2010-07-21T19:54:50.143 に答える