move, instead of copy, assignment

J

Jonathan Lee

Hi all,
I was wondering if there is a good way to detect an assignment from
an anonymous variable, so that the assignment might be accomplished by
a move, instead of a copy. For example:

MatrixClass x, y, z
// stuff happens to x, y, and z
// ...
z = x + y;

Suppose MatrixClass keeps a pointer to its data, which will be deleted
on destruction. Rather than copy (x + y) to z, it would be cheaper to
simply exchange the pointers inside the classes and allow the old z
data be deleted when (x + y) is destroyed.

Can such a thing be done automatically? Or would I have to use
something like

swap(z, x + y);

instead?

--Jonathan
 
J

Jonathan Lee

Hi all,
  I was wondering if there is a good way to detect an assignment from
an anonymous variable, so that the assignment might be accomplished by
a move, instead of a copy. For example:

K. Just minutes after posting this I discovered "rvalue references"
and "move semantics", for C++0x. And apparently, a template
specialization of std::swap is the agreed upon way of doing this
currently.

--Jonathan
 
A

Alf P. Steinbach

* Jonathan Lee:
K. Just minutes after posting this I discovered "rvalue references"
and "move semantics", for C++0x.

You'd need a compiler that supports that, though.

And apparently, a template
specialization of std::swap is the agreed upon way of doing this
currently.

Huh?

But anyway, within C++98 you can always try out Andrei's old Mojo library.

See article in DDJ.

However, there's no free lunch.

Mojo, as I recall, had a detrimental effect on some compilers' optimization.


Cheers & hth.,

- Alf
 
J

Jonathan Lee

* Jonathan Lee:
Huh?

I mean that a swap would effectively do what I want. And, as inelegant
as it is, the notation is common enough so that if someone were
reading
my code they wouldn't think "What the hell is this?"
But anyway, within C++98 you can always try out Andrei's old Mojo library..

Thanks, Alf. I'll take a look.

--Jonathan
 
M

Marcel Müller

Hi!

Jonathan said:
I was wondering if there is a good way to detect an assignment from
an anonymous variable, so that the assignment might be accomplished by
a move, instead of a copy. For example:

MatrixClass x, y, z
// stuff happens to x, y, and z
// ...
z = x + y;

You might think about reference type semantics for such complex objects.
I.e. different MatrixClass instances might refer to the same storage.

Firstly you could make the objects immutable. This is useful if
reassignments or changes typically require reallocation anyway.
(example: strings). If the objects are immutable you do not have to take
care of unexpected value changes because of the references.

But if the dimensions of your MatrixClass are likely not to change but
only the values change then immutable objects will cause far too many
reallocations. In this case you could use copy on write semantics. That
means that the matrix class firstly checks whether the reference counter
is 1, i.e. the storage is already private before it makes any changes to
the storage. Otherwise the assignment (or change) is made to new storage.

The disadvantage of the reference counting is that you typically have to
deal with threading issues. If normal thread safety satisfy your needs
(I.e. no threads copies MatrixClass instances that can asynchronously
change without a mutex. - I guess that is OK.), then a lock free
implementations is your choice. boost::intrusive_ptr should satisfy your
needs for the holder of the matrix storage.
Suppose MatrixClass keeps a pointer to its data, which will be deleted
on destruction. Rather than copy (x + y) to z, it would be cheaper to
simply exchange the pointers inside the classes and allow the old z
data be deleted when (x + y) is destroyed.

This is a common way, but it requires changes to the application code
rather then only changes to the library.
Also, if you want to benefit from in-place operations changes to the
application code are required. Example: assuming that not only x+y but
also x and y are temporary values you could write:

z.swap(x) += y;

which obviously does not require any additional allocation. But, the
readability is limited.

Another idea could use a proxy type for the rvalues of operator which
behaves different on assignment and copy construction. I don't know
about C++0x but the move semantics mentioned sounds similar.


Marcel
 
S

SG

  I was wondering if there is a good way to detect an assignment from
an anonymous variable, so that the assignment might be accomplished by
a move, instead of a copy. For example:

      MatrixClass x, y, z
      // stuff happens to x, y, and z
      // ...
      z = x + y;

Suppose MatrixClass keeps a pointer to its data, which will be deleted
on destruction. Rather than copy (x + y) to z, it would be cheaper to
simply exchange the pointers inside the classes and allow the old z
data be deleted when (x + y) is destroyed.

Yes, this is what you will be able to do with a "move assignment
operator" in C++0x:

class MatrixClass
{
std::vector<double> elements;
...
// copy assignment operator
MatrixClass& operator=(MatrixClass const& x) & = default;

// move assignment operator
MatrixClass& operator=(MatrixClass && x) &
{
this->clear();
this->swap(x);
return *this;
}
...
};

[Actually, I'm not sure whether the ref qualifier is legal in
combination with the =default; syntax. I hope that it is.]

Still, if operator+ returns a MatrixClass Objekt memory is allocated
(for the temporary object) and other memory is released again (after
swapping with the target object).

You could probably do even better with "expression templates" where
operator+ returns a "lazy matrix" that doesn't require a memory
allocation. The matrix class could have an additional assignment
operator that takes this "matrix expression" object and actually
evaluates it and stores the result directly. You can do this with C+
+98 already and I think this is what Boost.uBLAS does already.

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top