Boost logo

Boost :

Subject: Re: [boost] future/packaged_task Sean Parent designn
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-06-24 11:50:10


On 24 Jun 2015 at 16:30, Neil Groves wrote:

> > There is no reason for a packaged task implementation to be more heavy
> > weight than a promise. If the packaged task is [](T x) { return x; } then
> > it is also semantically equivalent to promise<T>, just in a nicer
> > interface. Bonus points it works beautifully with ASIO without any explicit
> > support from ASIO itself.
>
> I think this is a very important point. Of course the interaction is better
> with most existing code bases of which ASIO is merely one (important)
> example. It is clear that in at least some cases the packaged task
> implementation need not add overhead. Does anyone have any examples where
> one needs the additional abstraction for optimal performance?

Yes:
https://boostgsoc13.github.io/boost.afio/doc/html/afio/reference/class
es/enqueued_task_r___.html

std::packaged_task has a very unhelpful design for real world
programming. The ability to extract its its internally held promise,
and optionally set it early within the task is exactly what
afio::enqueued_task does.

If I remember rightly, I added a good 30% to performance using this
slightly enhanced packaged_task. For real world sized tasks this
stuff matters.

> > His implementation uses a shared ptr, but I think you could do without by
> > deep copying the futures and internally chaining via then. This way you
> > only pay the cost if you actually copy.
>
> Is there any data about this trade-off? It seems that requiring a deep copy
> could, at least under some use-cases be substantial overhead. With a deep
> copy requirement are you prohibiting a wrapper that uses a shared_ptr? It
> seems more idiomatic to default to value-type semantics while providing
> flexibility to reduce copy/clone overhead.

This is effectively the same as a linked list, and that is terrible
for performance after a certain depth of chains. You're better off
allocating memory and using shared_ptr after a certain depth.

> > I strongly believe that 'then' and other accessors should be non const so
> > that concurrent calls *on the same future* need not be supported.
> >
>
> Is this a necessary logical result of the const-ness, or do you mean you
> desire the absence of const to be able to assert misuse? I'm wondering if
> we can define a desing contract such that some futures may be called
> multiple times while for others this is not allowed. This doesn't seem like
> it ought to be part of the future interface, but more a contract of the
> abstractions being operated upon by the future. Perhaps I'm not
> understanding a use-case?

future<T> returns a one-shot value. Therefore its .then() is also
one-shot because it equals consuming any future value. This makes
total sense.

shared_future<T> returns its value as often as desired. In that
circumstance it is implied that more than one thread could fetch a
value. It therefore needs to be thread safe.

AFIO uses a lot of shared_future<T> currently, and it's all done
under the assumption that it's thread safe. I'd assume so does any
other code using shared_future<T>. I think the ship has sailed on
that design choice.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ 
http://ie.linkedin.com/in/nialldouglas/



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