Boost logo

Boost Users :

From: Kirit Sælensminde (kirit.saelensminde_at_[hidden])
Date: 2007-07-12 00:51:41


Edd Dawson wrote:
> Hi folks,
>
> I'm currently attempting to create a little facility that will allow me
> to eaily kick off a function call in another thread and get the result
> through a "future". Something like:

[snip]

> To achieve this I'm using boost::bind and boost::function quite heavily.
> I've discovered that by the time the final boost::function<void ()> is
> composed for the boost::thread constructor, I've copied each of the
> arguments (such as 9876543210 in the above) about 30 times!.

I've done what you're describing. I've not looked to see how many times
the arguments are copied though. It does sound a bit extreme.

I wouldn't start a new thread for each invocation though. Normally you'd
be better off re-using an earlier thread. Unless you're talking about
very large parameters the thread start up and shut down will probably
still take longer than the argument copying, but you'll have to take
timings to be sure.

>
> Now, I can use boost::ref() internally in such a way that no copying of
> arguments happens at all. However, this is also undesirable; I would
> like the thread that is created to have its own copy of each argument
> unless the client explicitly wraps an argument in boost::ref/cref in
> order to avoid dangling cross-thread references.
>
> So what I'd like is a way to copy the result of my final boost::bind()
> call in to a new functor where all the ref() arguments are deep-copied
> once and only once at the end.

Why not copy them once at the beginning into a structure with a pointer?
I've not looked at how I might do this in mine, but I imagine our
architectures aren't that dissimilar -- I use multiply nested functions
that wrap the functions to execute at the higher levels into the new
function signatures needed by the lower levels.

Note that the refs you're talking about are probably the same number of
bits as the integer. What you really need to do is to decide whether to
just copy the argument or not depending on what the argument is.

One thought might be to create a mismatch between the function signature
and what you're passing in. Say your prime number function took a string
as an argument. Normally you would do this:

long primes( const std::string &bignum );
std::string limit( "9876543210" );
async::call(cage, &count_primes_upto, limit );

This will copy the string a load of times. But wouldn't this copy it
once at the end when passed into primes?

long primes( std::string bignum );
std::string limit( "9876543210" );
async::call(cage, &count_primes_upto, boost::ref( limit ) );

Another alternative that might work for strings is this:

long primes( const std::string &bignum );
std::string limit( "9876543210" );
async::call(cage, &count_primes_upto, limit.c_str() );

That should force a string constructor only at the end of the chain, the
rest of the time passing a pointer.

I'm not sure if any of those will work, or if they will really address
your problem though. Maybe something to try?

K


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net