This mechanism has had quite a development path detailed as follows:
Shared Memory Transport (SHM)
The development started with the Shared Memory (SHM) transport, enabling fast communications between entities running in the same processing unit/machine, providing a better performance than UDP and localhost, mainly due to:
- Large message support without fragmentation
- Reduce number of memory copies (specially when there is more than one data reader)
- Less operating system overhead
The Shared Memory Transport works in order to deliver the data messages to the appropriate Domain Participants.
Data Sharing Delivery
Following the Shared Memory transport, the Data Sharing delivery provides a communication channel between entities within the same machine by sharing the history of the DataWriter with the DataReader through shared memory. This prevents any of the overhead involved in the transport layer, effectively avoiding any data copy between DataWriter and DataReader.
In the above image, you can see how, when the DataWriter is created, Fast DDS will pre-allocate a pool of max_samples + extra_samples samples that reside in a shared memory mapped file. When publishing new data, the DataWriter will take a sample from this pool, add a reference to it in its history, and notify the DataReader which sample from the pool holds the new data.
Now, the ultimate data transport mechanism has finally arrived: the ZERO-COPY communication. This communication can be achieved between publishing and subscribing applications by taking advantage of the following three features:
- Data-sharing delivery: as described above, it provides a copy-less communication channel between a Datawriter and a DataReader using shared memory.
- DataWriter sample loaning: a Fast DDS extension, which allows to borrow a sample buffer from the publishing DataWriter. Doing so, the application can write data in this buffer directly, thus eliminating the necessity of a copy between application and DataWriter.
- Loans from the DataReader: The application gets the received samples as a reference to the receive queue itself. This prevents the copying of the data from the DataReader to the receiving application. Again, if Data-sharing delivery is used, the loaned data will be in the shared memory, and will indeed be the same memory buffer used in the DataWriter history.
In the end, the users are able to save time and resources. You can find multiple examples of different use cases in the eProsima Fast DDS Github repository and the specific ZERO-COPY transfer here.