google / flatbuffers

FlatBuffers: Memory Efficient Serialization Library
https://flatbuffers.dev/
Apache License 2.0
23.28k stars 3.25k forks source link

How to achieve zero-copy for binary blob #4927

Closed aaronovz1 closed 6 years ago

aaronovz1 commented 6 years ago

Is there a way to reduce allocations and copying of binary blobs by getting FlatBufferBuilder to use the binary data directly? In my use case I pull frames from a camera, serialize them with FB, and then broadcast over ZMQ. The problem I am facing is that the image data is being deep copied and this is hurting performance. I read that using CreateUninitializedVector plus memcpy is slightly better than using CreateVector but it's still not great.

The trimmed down sample of what I am doing currently:

table Image
{
  width:int16;
  height:int16;
  bpp:int8;
  data:[byte];
}

size_t image_size = image->rows() * image->stepBytes();
uint8* frame_data_buf = nullptr;
auto frame_data_fb = fbb->CreateUninitializedVector<uint8>(image_size, &frame_data_buf);
memcpy(frame_data_buf, image->scanLine(), image_size); // BAD BAD BAD

Thanks

rw commented 6 years ago

I'm not an expert on the C++ port but are you saying you want the FBB to not write the image data into its owned buffer?

aaronovz1 commented 6 years ago

I guess I was trying to find a way to avoid the memcpy but I'm not really seeing how that would be possible. The only way I can achieve it in our setup is to the pull the image blob out of FB and send it separately as-is.

aardappel commented 6 years ago

Generally FlatBuffers cannot refer to external data.

One thing you could try is:

This avoids the memcpy, assuming ZeroMQ can pull its data from 2 buffers.

aaronovz1 commented 6 years ago

This is pretty much what I ended up doing. ZMQ has a concept of message parts, so I store the FB in one part, and the blob in a second part.