← Back to team overview

dolfin team mailing list archive

Re: [Branch ~dolfin-core/dolfin/main] Rev 4461: Work on mesh refinement interface.

 

On Mon, Feb 08, 2010 at 08:27:56PM -0800, Johan Hake wrote:
> On Monday 08 February 2010 13:57:34 Johan Hake wrote:
> > On Monday 08 February 2010 13:46:20 Anders Logg wrote:
> > > On Mon, Feb 08, 2010 at 01:43:35PM -0800, Johan Hake wrote:
> > > > On Monday 08 February 2010 13:41:29 Anders Logg wrote:
> > > > > On Mon, Feb 08, 2010 at 01:35:16PM -0800, Johan Hake wrote:
> > > > > > On Monday 08 February 2010 01:15:12 Anders Logg wrote:
> > > > > > > On Sun, Feb 07, 2010 at 11:25:28PM +0000, Garth N. Wells wrote:
> > > > > > > > Anders Logg wrote:
> > > > > > > > > On Sun, Feb 07, 2010 at 10:58:44PM +0000, Garth N. Wells
> wrote:
> > > > > > > > >> Anders Logg wrote:
> > > > > > > > >>> This looks a like a non-optimal solution. Are you returning
> > > > > > > > >>> the mesh by value? That will lead to creation of a
> > > > > > > > >>> temporary and copying of the entire refined mesh.
> > > > > > > > >>
> > > > > > > > >> So they used say ;). Apparently modern compilers are all
> > > > > > > > >> clever enough not to.
> > > > > > > > >>
> > > > > > > > >> Garth
> > > > > > > > >
> > > > > > > > > Is that really so? Do you have any good references that
> > > > > > > > > explain this in detail?
> > > > > > > >
> > > > > > > >   http://en.wikipedia.org/wiki/Return_value_optimization
> > > > > > > >
> > > > > > > > and from 'man gcc'
> > > > > > > >
> > > > > > > > -fno-elide-constructors
> > > > > > > >   The C++ standard allows an implementation to omit creating a
> > > > > > > > temporary which is only used to initialize another object of
> > > > > > > > the same type. Specifying this option disables that
> > > > > > > > optimization, and forces G++ to call the copy constructor in
> > > > > > > > all cases.
> > > > > > >
> > > > > > > ok, seems correct. I tried the following piece of code with some
> > > > > > > debugging added to the copy constructor and assignment operator
> > > > > > > in class Mesh:
> > > > > > >
> > > > > > >   Mesh refined_mesh_1 = UniformMeshRefinement::refine(mesh);
> > > > > > >
> > > > > > >   Mesh refined_mesh_2;
> > > > > > >   refined_mesh_2 = UniformMeshRefinement::refine(mesh);
> > > > > > >
> > > > > > > The first refinement does not lead to any call to either of the
> > > > > > > copy constructor or assignment operator.
> > > > > > >
> > > > > > > The second call leads to one call to the assignment operator.
> > > > > > >
> > > > > > > This is expected but means we need to be careful with how the
> > > > > > > refinement is called (on the same line as initialization).
> > > > > > >
> > > > > > > Should we have a look and see if there are other places where we
> > > > > > > could return by value?
> > > > > >
> > > > > > The operator* and operator+ were explicitly not included because
> > > > > > they needed to be implemented as a return by value method. Now they
> > > > > > can be added in the same way as the Python equivalents I think.
> > > > >
> > > > > You mean in the linear algebra interface?
> > > >
> > > > Yes.
> > >
> > > You could try. I wouldn't mind being able to do A = B + C in C++.
> > >
> > > But perhaps the complexity of the wrapper clases/interfaces will
> > > prevent the compiler from finding the suitable optimizations.
> >
> > Yes, you mentioned that.
> >
> > I think the implementation would just look something like:
> >
> >    GenericMatrix opertor+(const GenericMatrix& A)
> >    {
> >       GenericMatrix B(*this);
> >       B += A; // or B.axpy(1.0, A, false);
> >       return B;
> >    }
>
> The above is of course not valid as GenericMatrix cannot be instantiated. If
> we want to do it this way we need to implement it in the different subclasses.
> Any other suggestions?

Wouldn't this be a simple solution:

  GenericMatrix opertor+(const GenericMatrix& A)
  {
    GenericMatrix* B(copy());
    (*B) += A;
    return *B;
  }

--
Anders

Attachment: signature.asc
Description: Digital signature


References