Boost logo

Ublas :

Subject: Re: [ublas] Move Semantics
From: Jesse Perla (jesseperla_at_[hidden])
Date: 2009-09-10 20:05:39


On Thu, Sep 10, 2009 at 5:43 PM, Nasos Iliopoulos <nasos_i_at_[hidden]>wrote:

> Jesse,
> >I don't know that much about this stuff, but my understanding is that
> rvalue refereces and move semantics allow a library to overload the rvalue
> assignment to do a this kind of pointer swapping. But this stuff is
> probably very difficult to do.
>
>
I guess I knew what I was talking about when I suggested I don't know what I
am talking about.

> That's the trick data().swap(..) does, it takes the passed by value data
> and swaps its pointer with the object calling it <--I can discuss a bit more
> about that but it may get too technical (i.e. std::swap(..,..) vs
> container.swap(...) ). Also the compiler should be (in my case is)
> responsible to take care of the value passed using copy elision. If it is an
> rvalue it will pass it in without copying; or copy it if it is not - which
> is what we want.
>
> I did some tests and if the you are interested I can prepare to post them.
> The memory in those tests certainly shows half memory usage with move
> semantics for a large vector. Tracing back gives no indication of the
> existence of two containers and the performance is increased by about
> 20-30%. Also there is no indication of shallow copy (left and right side
> containers remain two distinct objects with distinct storage).
>
>
Wow... is it really that easy? I thought the above code would cause all
sorts of aliasing disasters...

Is this really good enough to use for functions returning big matrices as
return values?

Take the following:
template<typename MatrixT>
matrix<double> inv(const matrix_expression<MatrixT>& A)
{
  matrix<double> B(A().size1(), A().size2());
  //Say a complicated sequence to invert A into B, which can't just return a
matrix expression.

return B;
}

vs. a standard one with the return value passed in by non-const reference.
template<typename MatrixT>
void inv(const matrix_expression<MatrixT>& A, matrix<double>& B)
{
  //Complicated sequence to invert A into B, which can't just return a
matrix expression.
}

//Now take the client code, for very large matrices.
matrix<double> B = inv(A); //Does the swap method above cause an invalid
data pointer due to returning a temporary?

Any overhead in the copy vs. inv(A, B); ?

//Now do it with matrix expressions on both sides...
matrix<double> B = 2 * inv( .5 * A);

Is there any overhead on this vs.:
matrix<double> B(A.size1(), A.size2());
inv(.5 * A, B);
B *= 2;