Project

General

Profile

Actions

Task #1265

closed

Multi-buffer send operation on transport

Added by Alex Afanasyev over 11 years ago. Updated over 11 years ago.

Status:
Closed
Priority:
High
Category:
-
Target version:
-
Start date:
02/18/2014
Due date:
% Done:

100%

Estimated time:

Description

boost::asio support non-consecutive memory blocks to be used within the same send operation. This feature is necessary to support multiple LocalControlHeaders for the same Interest/Data.

As part of this issue is changing logic of memory management for LocalControlHeader. It is no longer is an extension of Interest/Data wire, but is independent piece that is stored in a separate memory buffer and is prepended to the Interest/Data wire during send operation.

Actions #1

Updated by Alex Afanasyev over 11 years ago

  • Project changed from NFD to ndn-cxx
  • Assignee set to Alex Afanasyev
  • Priority changed from Normal to High
Actions #2

Updated by Davide Pesavento over 11 years ago

Would be nice to have scatter/gather on the receive side too. I was trying to implement it inside StreamFace today, using a boost::circular_buffer, but I got stuck because Block constructor seems to require a single continuous memory buffer. It shouldn't be hard to do and it could save ourselves at least one memory copy operation in the receive path.

Actions #3

Updated by Alex Afanasyev over 11 years ago

It could be nice, but I don't clearly see real value. The copy operation in the receive is really an artifact that I currently have and can be (partially) easily avoided even without circular buffer: for each new read, just allocate maximum packet size buffer and read, and then create Block from the buffer directly (or multiple blocks from the same buffer, if it happened to be the case).

In any case, I checked and it seems that circular_buffer is only in boost 1.55...

Actions #4

Updated by Alex Afanasyev over 11 years ago

  • Status changed from New to Code review

I made a very simple implementation, just allowing two unrelated Block's to be passed to transport's send operation. Similar thing could be implemented inside NFD inside StreamFace.

Actions #5

Updated by Alex Afanasyev over 11 years ago

  • % Done changed from 0 to 100
Actions #6

Updated by Junxiao Shi over 11 years ago

for each new read, just allocate maximum packet size buffer and read, and then create Block from the buffer directly (or multiple blocks from the same buffer, if it happened to be the case).

This solution will not work.

Suppose maximum block size is 8 octets, and a letter indicates the beginning of a packet:

  1. Incoming stream is A1234B123C12
  2. First read operation receives A1234B12, and delivers block A1234.
  3. Second read operation receives 3C12. It must combine B12 left over from first read operation with 3 to deliver a continuous block.

There is a trick to avoid copy and receive exact blocks:

  1. Read 10 octets.
    This is guaranteed to contain INTEREST-TYPE | DATA-TYPE and TLV-LENGTH.
    This is also guaranteed not to contain more than one block, because the smallest possible block is .... which is 10 octets.
  2. Based on TLV-LENGTH, allocate a buffer enough for the whole block including the first 10 octets, write the first 10 octets into the buffer, and receive subsequent octets.

This trick trades an extra read(2) syscall for a memory copy operation of a whole block. Benchmark is needed to compare the overhead.

Actions #7

Updated by Alex Afanasyev over 11 years ago

I actually don't want to bother optimizing stream-based faces... Personally, I would prioritize datagram-based faces and optimize them, while having stream-based (TCP) just work.

Actions #8

Updated by Alex Afanasyev over 11 years ago

  • Status changed from Code review to Closed
Actions #9

Updated by Davide Pesavento over 11 years ago

Alex Afanasyev wrote:

In any case, I checked and it seems that circular_buffer is only in boost 1.55...

No, it first appeared in boost 1.35
http://www.boost.org/doc/libs/1_55_0/doc/html/circular_buffer/release.html

Actions #10

Updated by Alex Afanasyev over 11 years ago

oops. I was just changing 1_55_0 to different versions and if the page not there, I assumed it wasn't in the library. In that case, we can investigate this optimization, which in part should be in ndn-cpp-dev (different Block implementation).

Actions

Also available in: Atom PDF