[zeromq-dev] Very Small Messages/Manual

Ben Kloosterman bklooste at gmail.com
Mon Jul 26 10:44:53 CEST 2010


>Ben,
 >
 >> Using the union appeared to work well ( and I'm primarily interested
 >here as
 >> I want to introduce a variable size by copy message for my queue which
 >a
 >> union makes easier)
 >
 >Yes. I was thinking of introducing the union myself. The problem is that
 >changing the zmq_msg_t layout would break some of the language bindings,
 >so it has to be done carefully...

Completely agree.. I have made the changes but not experienced enough to
submit them.  I also want to add a new variable length copy message type for
my own InProc queue.

Most just use the get size and get data pointer , I found it pretty easy to
change the code. 
 

>
 >> The pack(1) was interesting and had a greater cost than I expected ,
 >that
 >> being said it made messages smaller which  provided a benefit to the
 >smaller
 >> ref based tests.
 >
 >At the level of optimisation going on here there are no magic solutions.
 >The structure of zmq_msg_t has to crafted by hand to get the best
 >performance.

Yes , I do think the sizeof should be a multiple of 16 or preferably 32. 

 >
 >> A better option may be to just use a int for a flags and size field ..
 >use
 >> the first 8 bits for size and just cast it to a byte from an int the
 >flags
 >> can work on the higher bits. Alternatively you can make the size 24
 >bits and
 >> flags 8 bits removing the need for a separate size field in the ref
 >based
 >> message ( unless anyone can see a reason for > 24 bit messages?).
 >>
 >> You then have small messages  up to size 28 and still fit in 32 bytes
 >( even
 >> on 64 bit machines)  , may try that now and force 16 byte alignment..
 >
 >I though of something like this:
 >
 >struct zmq_msg_t
 >{
 >     union {
 >         void *ptr;
 >         struct {
 >             ...
 >         } vsm;
 >     } content;
 >     unsigned char type;
 >     unsigned char flags;
 >}
 >
 >In theory, it would make VSM messages smaller (no content pointer).
 >However, in practice, you'll get 6 bytes (x86_64) of padding following
 >the structure -- because of compiler aligning it to CPU word boundary.

Yes that's why a sizeof() based on a paragraph will help. Here is what I now
have with a Max_size of  12, 28 , 44 or 60.   It should also work just as
well on 64 bit though prob better to be sure it is packed to 32 bit.  Very
similar. 

	#pragma pack(4)  //ensures fields are not packed  on 8 byte
boundaries
      typedef struct
	{
		void *content;
	} zmq_m_t;

	typedef struct
	{
	
		unsigned char vsm_data [ZMQ_MAX_VSM_SIZE];
	} zmq_vsm_t;


	typedef union 
	{
		zmq_vsm_t  vsm;
		zmq_m_t   m;
		zmq_var    var; // variable sized by copy messages.

	} zmq_msgdata_t;


	__declspec(align(16))  //TODO make portable  //good for SSE2 
		typedef struct
	{
		
		zmq_msgdata_t  msgs; // on some compilers the data field
will be first and on a boundary
		unsigned flags : 8 ;
		unsigned vsm_size : 24;

		inline bool Is_VSM()
		{
			return (flags & ZMQ_MSG_VSM)  !=0;
		}

	} zmq_msg_t;
#pragma pack()

Note since it was free due to 32 bit alignment ( and the slight drop by
using 8 bit pack(1)  I put message size here , and then  removed the other
size field , this means max message drops from 4G  to 16 Meg  but personally
16 Meg is more than enough for a single message.  The bit fields were faster
than packed byte fields. 

Regards, 

Ben 





More information about the zeromq-dev mailing list