Q: Use struct or not ?

3 posts / 0 new
Last post
frgo's picture
Offline
Last seen: 6 years 8 months ago
Joined: 12/28/2011
Posts: 20
Q: Use struct or not ?

Hi all:

I am new to DDS and I am currently designing an IDL for exchanging messages between applications. For defining complex data there is now the question of using structs or not, as shown here:

// PIB Network Participant

struct participant_t
{
string<36> id; //@key
unsigned long rtps_host_id;
unsigned long rtps_app_id;
unsigned long rtps_instance_id;
string application;
string hostname;
long process_id;
long thread_id;
};

// PIB Message Structure: Header

struct msg_header_t
{
string<36> id; //@key
participant_t sender;
participant_t receiver;
};

The second struct could also be written as:

struct msg_header_t
{
string<36> msg_id;

// Sender

string<36> sender_id; //@key
unsigned long sender_rtps_host_id;
unsigned long sender_rtps_app_id;
unsigned long sender_rtps_instance_id;
string sender_application;
string sender_hostname;
long sender_process_id;
long sender_thread_id;

// Receiver

string<36> receiver_id; //@key
unsigned long receiver_rtps_host_id;
unsigned long receiver_rtps_app_id;
unsigned long receiver_rtps_instance_id;
string receiver_application;
string receiver_hostname;
long receiver_process_id;
long receiver_thread_id;
};

I am targeting very fast (real time) message exchange, round trip time < 5 ms. The generated code will be C language based - and is quite less complex in the second approach. I have not yet used the RTI apps like RTI Monitor etc.

Is there any clear way of saying which one will be "faster" and which one will be "better to maintain, better to implement"? I know it's difficult to give any clear statement based on that little info I can give... I guess it boils down to "How would you do it ? Why?"

Thanks for sharing thoughts!

Best regards

Frank

Gerardo Pardo's picture
Offline
Last seen: 3 weeks 5 days ago
Joined: 06/02/2010
Posts: 602

Hello Frank,

The use of nested structures does not carry any significant penalty at run-time.  The consequence of using the first design (the nested struct participant_t ) versus the second will be two additional function calls during serialization and deserialization. This is because each time you declare a data-structure (such as the struct participant_t)  the code generator will create a corresponding  "participant_t_Serialize()" and "participant_t_Deserialize()" which will be called recursively  when you serialize (or deserialize) msg_header_t. You can see the difference if you run rtiddsgen on the two types and inspect the "Serialize" and "Deserialize" functions that are generated.

I would definitely recommend the first approach  (defining a separate participant_t struct).  In practice an extra function call introduces negligible overhead, in the order of tens of nanoseconds in modern processors. So it will be totally un-observable to you, especially when you consider everything else that is associated with serializing the sample and sending it to all the subscribers on the network or shared memory.   From the design and maintenance point of view the first approach is far better as it avoids duplication of that type definition.

I am curious regarding the definition of the types themselves. Do they resemble the data you are trying to send?  If so it seems that you are sending a lot of information that is already sent in meta-data by RTI DDS so you really do not need to include it in your data type.

For example, all the rtps_* attributes are sent already via discovery at the time a participant is first discovered and whenever to get a sample you can access that information through the meta-data in the SampleInfo so you do not need to put it explicitly as part of your data.

Gerardo

frgo's picture
Offline
Last seen: 6 years 8 months ago
Joined: 12/28/2011
Posts: 20

Gerardo,

thank you very much for your quick and enlightening response. Much appreciated! I now have optimized the data structures as per your suggestions.

Kind regards

Frank