Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2008-05-13 18:18:20


On Tue, May 13, 2008 at 11:11 PM, Marco Costalba <mcostalba_at_[hidden]> wrote:
> On Tue, May 13, 2008 at 9:32 PM, Giovanni Piero Deretta
> <gpderetta_at_[hidden]> wrote:
> >
> > // adding all overloads, If I can get it my way :)
> > struct foo_fwd {
> > template<typename T>
> > void operator()(T x) {
> > foo(x);
> > }
> > };
> >
> > my_msf f = foo_fwd();
> > //sizeof(f) = O( sizeof(boost::function) )
> >
> >
> > Comments? Did I convince you? ;)
> >
> >
>
> Yes ;-) I'll stick to one_copy_only behaviour for set_all()
>
> But because to implement the N copy case is trivially simple (much
> simpler then your example) I would like to change the signature of
> set_all in the following way
>
> template<typename Fun>
> void set_all(Fun const& fun, bool multi_instance = false);
>
> Regarding the sizeof(f) == O( sizeof(boost::function) * N ) problem, given that
>
> - boost::function object are member data, so allocated on the stack

Hum. I'have used vectors of boost::function objects. Those are
definitely not allocated
on the stack, and when you have many of them, size starts to matter, and
for many signatures the size difference is significant. I do not think
this usage is exceptional,
in fact boost::signals does exactly that as it keeps a list of
boost::functions as callback.

I intend to use MSF as a replacement for boost::function, and I will
definitely use vectors of MSF.

> - boost::function object are created at MSF instantation (seldom event
> or not in critical loop context?),
> not during assignment (more often
> event, more performance critical ? )

Copyng N boost::function objects will require N indirect function
calls instead of one for
the straight forward implementation.

Probably it is not likely to be a bottleneck, but I would not like to
pay for what I do not use.
 The implementation seems needlessly complex :)

Also, the extra complexity in the implementation might (or might not)
have an effect on
compile time.

>
> I would like to know if
>
> - boost::function default c'tor does some allocation? An empty
> boost::function is cheap to create ?
>

You can assume so.

> - When a functor is assigned by reference with boost::ref
> boost::function just copies a pointer/reference ?
>

Since boost-1.34, It should no longer require dynamic memory
allocation (due to small object optimization),
but that is not guaranteed. Also there will be hard for the compiler
to optimize away all the indirect function calls required to copy the
stored object.

In general a non empty boost::function construction and copy imply
a memory allocation.

> If the above it's true, but I am not an expert of boost::function, the
> problem of allocation of N boost::function perhaps is more theoretical
> then real, also the size problem, given that boost::function requires
> just 3 pointers does not seem a biggie IMHO.
>

Well. You can implement msf with just two pointers:
one to the virtual table (which is per signature set and not per instance)
and one to the actual (heap allocated functor). I think that boost::function has
space for an extra pointer so that bound member functions can benefit
from SOO, thus sizeof(boost::function) is (usually) sizeof(void*)*3.

Your implementation uses at least sizeof(void*) * 3 * N, where N is
the number of signatures.
In addition I think it requirs an extra pointer to point to the function object.

This is very, very wasteful: if you have a vector of msf even of
moderate size, the multiplier
might be the difference between fitting and not fitting in the cache.

Larger stack might also be a problem for threaded programming.

In addition you have to consider the N indirect calls you have to do
for each copy,
comparision etc...

>
> BTW remember the resul_of implementation request?
> [...]
> It is very simple, I even don't believe it can work...but it does :-)
>

Great! :)

-- 
gpd

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk