[cpp-threads] Asynchronous Function Proposal

Herb Sutter hsutter at microsoft.com
Sun Jun 14 00:31:47 BST 2009


I've now looked at the proposal further. It has implemented some of the changes suggested in the earlier thread, but still hasn't implemented some that I consider essential. In particular (and I don't think I was the only person to argue for these):

  - The async policy parameter is still first, and we don't need a variadic
    overload. There should be just one async() with a defaulted policy parameter.

  - The wording for the first policy still says "in a new thread," which
    prevents the implementation from caching threads in any way (including the
    highly desirable option of running on a thread pool). It should say "in
    another thread."

  - There is still a new future type, async_future. It should be unique_future.
    (In related news, the return type of async() should be convertible to
    shared_future. Adding a conversion from async_future to shared_future would
    satisfy that part, but not satisfy the main point in this bullet.)

As I mentioned to Lawrence privately last week, I strongly prefer to avoid having competing proposals for Frankfurt, but I feel strongly enough about these issues that if we feel we don't have consensus to word this proposal this way, I'm willing to write a competing proposal to make sure a version that looks like the above appears in an on-time paper for consideration in Frankfurt.

Less importantly, the policy names are awkward. I'd prefer names more like "elsewhere/here/either" or "async/sync/either" or "this_thread/another_thread/either".

Also, whether we diverge proposals or not, I would like to see this paragraph reworded:

  > The proposed solution consists of a set of async functions to launch
  > asychronous work and a new kind of future to manage the function result.
  > This solution derives from an extensive discussion on the C++ threads
  > standardisation <cpp-threads at decadentplace.org.uk> mailing list.

That wrongly implies that the discussion blessed/suggested both the "set of async functions" and "a new kind of future" design points -- both of which I and others have objected to. At minimum this needs to acknowledge that there were strong objections against both of these features.


> The model for this feature, as I understand it, is to provide a means
> for people with a sequential program to easily upgrade it to exploit a
> small number of cores.

No, it's simply to provide a simple means to perform an async function call that yield an async result, that is instead of

  T t = f();

to write (I'll say just "future" to avoid the argument about the exact type here)

  future<T> t = async( []{ f(); } );

without writing packaged_tasks and having to fill futures/promises manually.

Beyond that basic requirement, there's also the desire (which the proposal already supports, thanks!) to allow, but not require, implementations that run the task on a thread pool or a work stealing runtime. To enable all of that, it's sufficient to have the three options "on this thread," "on a different thread," or "either." The latter two enable thread pools; the last alone enables work stealing.

    Policy              new thread    thread pool     work stealing

    on this thread         no            no               no
    on another thread      yes           yes              no
    either                 yes           yes              yes


> Switching to unique_future can be done relatively easily at Frankfurt.

No, I want there to be a concrete on-time proposal on the table in Frankfurt whose basic parts look correct to me, including that it does not invent some new future type and the other major points above.

I wasn't the only one who argued against having yet another future type only for use with async. I want async() to return a unique_future and I am happy with requiring the implementer to make it work. (Yes, it would be better still if unique_future and shared_future more easily let us accomplish what we want, but that's not necessary to have async() return the correct type, which I believe is unique_future as long as that remains convertible to shared_future.)

> Creating an async_future proposal at Frankfurt would not be easy.  So,
> in the interests of leaving our options open, 

It's not an option I want to see open. ;-) We have a future type; we should use it. I do not think this is a case where it's desirable to keep options open, because inventing a new one-off future type is just undesirable.

If you want to keep it in this proposal that's fine, but I disagree and I need there to be some proposal for Frankfurt that uses unique_future.

> I addressed the choice in the paper,
> and I'll happily expand that section to meet your concerns.

I appreciate that, and I'd be okay with the proposal introduction mentioning this discussion and the pros/cons of using a separate future type -- as long as the proposed text itself uses unique_future and doesn't invent a new future type.

Are you open to doing a revision along those lines, as well as the other points at top? I understand if you're not and either way I do appreciate the work you've put into this and the very useful discussion it has made possible! Thanks Lawrence,

Herb





More information about the cpp-threads mailing list