Trying to understand how many copies of data there'll be if I send with `dds_writecdr`
Hi there. Recently I've been using DDS writecdr a lot. Our middleware prepares a std::vector<std::byte> which contains a CDR-serialized message(plus the four bytes CDR headers), then calls dds_writecdr
const ddsrt_iovec_t data_iovec{send_msg_data.data(), send_msg_data.size()};
auto* serdata = ddsi_serdata_from_ser_iov(sertype, SDK_DATA, 1U, &data_iovec, send_msg_data.size());
const auto write_ret = dds_writecdr(writer, serdata);
My understanding is that CycloneDDS will skip the CDR serialization step, as we already did it using our framework. Just curious will CycloneDDS have extra copy over this buffer before it's sent to the network device?
From me tracing the code all the way to deliver_data_network and to write_sample, the sample will be written to a WHC. And I guess this is the only copy. Just to confirm my understanding is correct. Thanks!
Hi @t0ny-peng, the answer is: it depends on the sertype/serdata ... Assuming you use the "default" C implementation and the sertype of the writer matches the sertype you used here:
-
ddsi_serdata_from_ser_iovwillmemcpythe CDR fromsend_msg_data; -
dds_writecdrwill reference it from the packets to be sent usingsendmsg— the kernel will then copy it in; - it will reference the
serdatain the WHC if needed (not copy)
If the refcount of serdata is not 1 when you call dds_writecdr or there is a type mismatch it gets more complicated:
https://github.com/ZettaScaleLabs/cyclonedds/blob/53d135690a097ea69d9032183dd890b0fffd2a2b/src/core/ddsc/src/dds_write.c#L499-L510
but it seems unlikely you'd be running into that.