Discussion:
[zeromq-dev] C++ Move Constructor and Assignment Operator
Christoph Heindl
2013-02-14 07:38:40 UTC
Permalink
Hi,

I was using the Cpp ZMQ interface lately and while writing a bunch of unit
tests I came accross curious behaviour in the move constructor and
assignment operator of zmq::message_t.

The following tests fail (zmq 3.2.2, latest zmq.hpp from github, MSVC10)


zmq::message_t m0(10);
void *adr = m0.data();

zmq::message_t m1;
m1 = std::move(m0);

BOOST_REQUIRE_EQUAL(adr, m1.data());

It might be a semantic error on my side, but I would have thought that an
efficient implementation would happly reuse the buffer allocated by m0.
Instead i get a different buffer address. Similarily the move constructor
seems to re(a)locate the buffer

zmq::message_t m0(10);
void *adr = m0.data();

zmq::message_t m1(std::move(m0));

BOOST_REQUIRE_EQUAL(adr, m1.data())

Is this behaviour intended?

Btw. in zmq.hpp std::swap is used in the move assignment operator. This
seems to me as both buffers survive (at least temporarily) in a scenario as
described above ( zmq::message_t m1(std::move(m0))). I guess that has
something todo with the fact that closing the message is always done in the
destructor.

Best,
Christoph
R***@waters.com
2013-02-14 09:14:19 UTC
Permalink
Hi Christoph,

I believe zeromq does this is by design. It copies the data if the message size is small and reference counts it if its above a certain size.

It looks like the size threshold is specified by the max_vsm_size enum in msg.hpp, currently set to 29, so if you make your message size 30 it should
switch to reference counting.

Regards,

Richard.




From: "Christoph Heindl" <***@gmail.com>
To: zeromq-***@lists.zeromq.org
Date: 14/02/2013 07:38 AM
Subject: [zeromq-dev] C++ Move Constructor and Assignment Operator
Sent by: zeromq-dev-***@lists.zeromq.org



Hi,

I was using the Cpp ZMQ interface lately and while writing a bunch of unit tests I came accross curious behaviour in the move constructor and
assignment operator of zmq::message_t.

The following tests fail (zmq 3.2.2, latest zmq.hpp from github, MSVC10)


      zmq::message_t m0(10);
      void *adr = m0.data();

      zmq::message_t m1;
      m1 = std::move(m0);

      BOOST_REQUIRE_EQUAL(adr, m1.data());

It might be a semantic error on my side, but I would have thought that an efficient implementation would happly reuse the buffer allocated by m0.
Instead i get a different buffer address. Similarily the move constructor seems to re(a)locate the buffer

      zmq::message_t m0(10);
      void *adr = m0.data();

      zmq::message_t m1(std::move(m0));

      BOOST_REQUIRE_EQUAL(adr, m1.data())

Is this behaviour intended?

Btw. in zmq.hpp std::swap is used in the move assignment operator. This seems to me as both buffers survive (at least temporarily) in a scenario as
described above ( zmq::message_t m1(std::move(m0))). I guess that has something todo with the fact that closing the message is always done in the
destructor.

Best,
Christoph_______________________________________________
zeromq-dev mailing list
zeromq-***@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

===========================================================
The information in this email is confidential, and is intended solely for the addressee(s).
Access to this email by anyone else is unauthorized and therefore prohibited. If you are
not the intended recipient you are notified that disclosing, copying, distributing or taking
any action in reliance on the contents of this information is strictly prohibited and may be unlawful.
===========================================================
Christoph Heindl
2013-02-14 09:43:09 UTC
Permalink
Hi Richard,
Post by R***@waters.com
I believe zeromq does this is by design. It copies the data if the message
size is small and reference counts it if its above a certain size.
Ok, I did not know that. Would by interesting to know why. Is ZMQ using
some kind of small buffer optimization, where it uses the first few bytes
of the buffer for reference counter or storing the values if small enough?
Post by R***@waters.com
It looks like the size threshold is specified by the max_vsm_size enum in
msg.hpp, currently set to 29, so if you make your message size 30 it should
switch to reference counting.
I did and it works. Added both, positive and negative tests.

Thanks for the hint.

Best,
Christoph
R***@waters.com
2013-02-14 09:55:16 UTC
Permalink
I would presume it does it so it can avoid allocating on the heap for small messages.

If your message is < 30 bytes then it is stored within message_t, i.e. on the stack if message_t is on the stack, >= 30 bytes it mallocs some memory
(buffer size + sizeof(content_t) for some reference counting housekeeping).

Richard.




From: "Christoph Heindl" <***@gmail.com>
To: "ZeroMQ development list" <zeromq-***@lists.zeromq.org>
Date: 14/02/2013 09:43 AM
Subject: Re: [zeromq-dev] C++ Move Constructor and Assignment Operator
Sent by: zeromq-dev-***@lists.zeromq.org



Hi Richard,

On Thu, Feb 14, 2013 at 10:14 AM, <***@waters.com> wrote:

I believe zeromq does this is by design. It copies the data if the message size is small and reference counts it if its above a certain size.


Ok, I did not know that. Would by interesting to know why. Is ZMQ using some kind of small buffer optimization, where it uses the first few bytes of
the buffer for reference counter or storing the values if small enough?


It looks like the size threshold is specified by the max_vsm_size enum in msg.hpp, currently set to 29, so if you make your message size 30 it
should switch to reference counting.


I did and it works. Added both, positive and negative tests.

Thanks for the hint.

Best,
Christoph_______________________________________________
zeromq-dev mailing list
zeromq-***@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

===========================================================
The information in this email is confidential, and is intended solely for the addressee(s).
Access to this email by anyone else is unauthorized and therefore prohibited. If you are
not the intended recipient you are notified that disclosing, copying, distributing or taking
any action in reliance on the contents of this information is strictly prohibited and may be unlawful.
===========================================================
Christoph Heindl
2013-02-14 10:00:40 UTC
Permalink
Post by R***@waters.com
If your message is < 30 bytes then it is stored within message_t, i.e. on
the stack if message_t is on the stack, >= 30 bytes it mallocs some memory
(buffer size + sizeof(content_t) for some reference counting housekeeping).
That makes sense. Thanks for clarifying.

Best,
Christoph

Loading...