
Ponderings on the Futures Library: What is the status of Anthony Williams' submission of the futures library to the c++ standards committee? Is it more prudent to wait to find out what the c++ standards committe is going to do first, before adding a possibly incompatible version of the futures library to boost? One could ask, if Anthony's submission is approved by the c++ standards committe, what is the point of adding a "futures" library to boost as well? Is a seperate library needed? What is the advantage of having a root level library called boost::futures? Why would it not be perferable to just extend boost::thread with the additional capabiltity to handle "futures"? Futures are a very useful concept, and I have used them personally. The c++ commitee is correctly considering adding them to the standard. I would be interested in hearing the authors views on their "grand" vision for parallel programming in general and how their "futures" library submissions fit into this vision. tom brinkman

On Thu, 8 Jan 2009, Tom Brinkman wrote:
Ponderings on the Futures Library:
What is the status of Anthony Williams' submission of the futures library to the c++ standards committee?
Dunno.
Is it more prudent to wait to find out what the c++ standards committe is going to do first, before adding a possibly incompatible version of the futures library to boost?
Both approaches have benefits. - Early users may help the committee avoid bad decisions. - Waiting simplifies the life of end users.
One could ask, if Anthony's submission is approved by the c++ standards committe, what is the point of adding a "futures" library to boost as well?
If this exact submission were standardized, the Boost version would still be useful on older (standard) compilers.
Is a seperate library needed? What is the advantage of having a root level library called boost::futures? Why would it not be perferable to just extend boost::thread with the additional capabiltity to handle "futures"?
Not having read the code, it would seem the two should be separate unless they would benefit from heavy code reuse not available through the public APIs. More importantly, there should be benefits by having the boost::futures namespace closely reflect std::futures or whatever.
From the sidelines, Daniel

"Tom Brinkman" <reportbase@gmail.com> writes:
Ponderings on the Futures Library:
What is the status of Anthony Williams' submission of the futures library to the c++ standards committee?
Futures have been approved by the committee. They are part of the current working draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf Futures are chapter 30.5
Is a seperate library needed? What is the advantage of having a root level library called boost::futures? Why would it not be perferable to just extend boost::thread with the additional capabiltity to handle "futures"?
That was my intent. The presence of a separate futures library from Braddock meant that it was more prudent to offer both libraries up for review.
Futures are a very useful concept, and I have used them personally. The c++ commitee is correctly considering adding them to the standard. I would be interested in hearing the authors views on their "grand" vision for parallel programming in general and how their "futures" library submissions fit into this vision.
Ooh, now you're asking! My "grand" vision is that we will eventually have a C++ concurrency library that allows users to divide their code into potentially-parallelizable tasks and have the library manage the actual parallelization. I also think that the fewer user-level locks that are required the better. I think futures are a useful concept for communicating values between threads. They simplify communication because no explicit locking is required in the user code. They also allow value-returning functions to be run on other threads without the user having to explicitly marshal the result (normal or exceptional) across the thread boundary. Futures are also useful for thread pools --- you can submit a task to a pool, and obtain a future which becomes ready when the task has executed. Anthony -- Anthony Williams Author of C++ Concurrency in Action | http://www.manning.com/williams Custom Software Development | http://www.justsoftwaresolutions.co.uk Just Software Solutions Ltd, Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK

On Thu, Jan 8, 2009 at 3:41 PM, Anthony Williams <anthony.ajw@gmail.com> wrote:
"Tom Brinkman" <reportbase@gmail.com> writes:
Ponderings on the Futures Library:
What is the status of Anthony Williams' submission of the futures library to the c++ standards committee?
Futures have been approved by the committee. They are part of the current working draft:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf
And the technical content of N2798 is the same as N2800, which was shipped as CD-1 and is now in the ISO balloting process. CD-1 isn't intended to pass the ballot. Rather, it serves to put the world on notice that C++0x is feature complete. Essentially a fairly late beta release. That means that committee work on C++0x futures is done, except for corrections in response to ballot comments. It would be very unusual if futures did not make it into the final C++0x standard, and with little if any change from the current specification. What change do occur will be mostly tightening up the specification and tweaking the wording. Few if any new features will be added. So we should aim for the Boost threading library to conform to N2800 as closely as we can. It is OK to add extensions, but we shouldn't leave out features or change existing features, IMO. --Beman

Anthony Williams wrote:
My "grand" vision is that we will eventually have a C++ concurrency library that allows users to divide their code into potentially-parallelizable tasks and have the library manage the actual parallelization.
I've been waiting for that for a long time, but I don't know of any satisfying approach. Even OpenMP, which is included in the compiler and is supposed to do that kind of thing, will always parallelize and won't even consider a hierarchy between nested potentially-parallelizable tasks. I've even heard that nesting parallel tasks within other parallel tasks was ill-advised with OpenMP.

Mathias Gaunard-2 wrote:
My "grand" vision is that we will eventually have a C++ concurrency library that allows users to divide their code into potentially-parallelizable tasks and have the library manage the actual parallelization.
I've been waiting for that for a long time, but I don't know of any satisfying approach.
Even OpenMP, which is included in the compiler and is supposed to do that kind of thing, will always parallelize and won't even consider a hierarchy between nested potentially-parallelizable tasks. I've even heard that nesting parallel tasks within other parallel tasks was ill-advised with OpenMP.
For a lot of parallelizable problems, we can never hope for any particularily good programming models in a languages as C++ or with the desktop operating systems we have today. Needless to say, that shouldn't stop us from extracting as much parallel performance as we can from the current software stack. See the first part of my thesis at www.johantorp.com for an in-depth discussion. Best Regards, Johan Torp www.johantorp.com -- View this message in context: http://www.nabble.com/Pondering-Futures-tp21359362p21388144.html Sent from the Boost - Dev mailing list archive at Nabble.com.

Johan Torp wrote:
For a lot of parallelizable problems, we can never hope for any particularily good programming models in a languages as C++ or with the desktop operating systems we have today. Needless to say, that shouldn't stop us from extracting as much parallel performance as we can from the current software stack. See the first part of my thesis at www.johantorp.com for an in-depth discussion.
How to schedule optimally depends on the application, yes. Just let the user customize the scheduler behavior then. As for heterogeneous architectures, this is of course an open problem that C++ cannot solve because you cannot predict which piece of code will be faster on which processor. But I don't think C++-like languages are unable to do parallelization well on heterogeneous architectures, even those with NUMA effects.

Mathias Gaunard-2 wrote:
For a lot of parallelizable problems, we can never hope for any particularily good programming models in a languages as C++ or with the desktop operating systems we have today. Needless to say, that shouldn't stop us from extracting as much parallel performance as we can from the current software stack. See the first part of my thesis at www.johantorp.com for an in-depth discussion.
How to schedule optimally depends on the application, yes. Just let the user customize the scheduler behavior then.
That way you get non-portable code adapted for some particular architecture(s). Ideally you'd like code to execute well on future, non-existing processors too. Mathias Gaunard-2 wrote:
As for heterogeneous architectures, this is of course an open problem that C++ cannot solve because you cannot predict which piece of code will be faster on which processor. But I don't think C++-like languages are unable to do parallelization well on heterogeneous architectures, even those with NUMA effects.
It can be possible with knowledge of the hardware. But simply scheduling work onto N cores will not work well when you move to manycore processor, you'll need more complex hardware models. But knowledge about hardware should be in the operating system and drivers, not in user level code. Both to simplify coding and to get portable code. But even if you aim at non-portable code, C++ is a poor at expressing parallel code for many other reasons: - Threads are heavy-weight and difficult to program with (dead locks, race conditions, indeterminism, composability problems) and are very explicit. You can build some other flow control mechanisms (lighter such as fibers/co-routines, more implicit such as thread pools etc) but others (transactional memory, nested data level parallelism, etc) can't be implemented efficiently. - C++ has a UMA shared memory model and provides reference semantics without any sense of purity. You might need to have implicit or explicit control over where code is stored in memory too, C++ does not provide this. - There is no way to proactively load a cache or express that you intend to access certain memory locations. - You can not set up efficient data streams. As we move towards manycore and transistors become ubiquitous, it seems probable that you'd often like to schedule memory interconnect access rather than tasks. - You want to do scheduling based on all processes running, not per C++ application. If all applications have their own threadpools we might get better performance if none of them did. .NET can handle this. Now don't get me wrong. There's no one language that is going to be good at expressing all kinds of parallelism - we will need a lot of parallel programming models. C++ can be used for some basic parallel code but is poorly suited for a lot of others, especially when we go to manycore. Best Regards, Johan Torp www.johantorp.com -- View this message in context: http://www.nabble.com/Pondering-Futures-tp21359362p21398146.html Sent from the Boost - Dev mailing list archive at Nabble.com.

Johan Torp wrote:
That way you get non-portable code adapted for some particular architecture(s). Ideally you'd like code to execute well on future, non-existing processors too.
Scheduling doesn't have to be static. You can define an algorithm that scales to any architecture, and that favors processor usage, minimum migration between cores, keeping tasks that interact a lot together close, or whatever depending on what works best for your application. That scheduling algorithm could simply be a way to map a tree of tasks to a tree of processors, with some code triggered for some events (a processor is idle, some new tasks have been created, etc.) Task hierarchy defines task affinity, and topology hierarchy defines nested NUMA nodes, SMP, Multi-core, and SMT units (Hyperthreading). Such platforms already exist, at least in research. That's imagining a hierarchical topology and hierarchical tasks. Which is not always relevant since topologies often form graphs, but the abstraction is practical enough.
Mathias Gaunard-2 wrote:
As for heterogeneous architectures, this is of course an open problem that C++ cannot solve because you cannot predict which piece of code will be faster on which processor. But I don't think C++-like languages are unable to do parallelization well on heterogeneous architectures, even those with NUMA effects.
Ok, there is a problem here: I meant "I don't think C++-like language are unable to do parallelization well on *homogeneous* architectures, even those with NUMA effects". Sorry for the confusion.
But even if you aim at non-portable code, C++ is a poor at expressing parallel code for many other reasons: - Threads are heavy-weight
Only if you make them so. Kernel threads are fairly heavyweight, especially since you don't have much control over them, but user-level threads can be very lightweight. There is nothing inherently heavyweight about a "task". Well, except its stack, but that's more of a memory usage problem.
and difficult to program with (dead locks, race conditions, indeterminism, composability problems)
There are many problems with using shared memory concurrency, yes. There are other patterns though. Anyway here we were discussing about defining all tasks that can be parallelized as potentially-parallelizable and have a library parallelize them or not and schedule them well so that parallelization doesn't hurt more than it helps. Concurrency is kind of a different problem, I'd say.

On Sat, Jan 10, 2009 at 5:28 AM, Johan Torp <johan.torp@gmail.com> wrote:
[...] For a lot of parallelizable problems, we can never hope for any particularily good programming models in a languages as C++ or with the desktop operating systems we have today. Needless to say, that shouldn't stop us from extracting as much parallel performance as we can from the current software stack. See the first part of my thesis at www.johantorp.com for an in-depth discussion.
An excellent read; a nice single point reference for a lot of the things I've had bouncing around my head for the last couple years. Thanks! But of course now I'll have to go looking at all the references in chapter 6... :)

Oliver Seiler wrote:
On Sat, Jan 10, 2009 at 5:28 AM, Johan Torp <johan.torp@gmail.com> wrote:
See the first part of my thesis at www.johantorp.com for an in-depth discussion.
An excellent read; a nice single point reference for a lot of the things I've had bouncing around my head for the last couple years. Thanks!
But of course now I'll have to go looking at all the references in chapter 6... :)
Thanks. Most of the chapter six links are really easily digested, especially the video interviews. More interesting than most dramas :) Bear in mind who is speaking though, a lot of companies have strong interests in pushing the shift to parallel processors and software. Some statements and figures seem exaggerated to me. Best Regards, Johan Torp www.johantorp.com -- View this message in context: http://www.nabble.com/Pondering-Futures-tp21359362p21430502.html Sent from the Boost - Dev mailing list archive at Nabble.com.

----- Original Message ----- From: "Tom Brinkman" <reportbase@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, January 08, 2009 8:37 PM Subject: [boost] Pondering Futures
Ponderings on the Futures Library:
What is the status of Anthony Williams' submission of the futures library to the c++ standards committee?
Is it more prudent to wait to find out what the c++ standards committe is going to do first, before adding a possibly incompatible version of the futures library to boost?
One could ask, if Anthony's submission is approved by the c++ standards committe,
I think that it is already approuved.
what is the point of adding a "futures" library to boost as well?
We need it to make high level libraries, as we need a Move and Chrono library.
Is a seperate library needed? What is the advantage of having a root level library called boost::futures? Why would it not be perferable to just extend boost::thread with the additional capabiltity to handle "futures"?
The namespace has no importance. The future classes can leave on the boost namespace. Anthony even has put on the jss namesspace. I don't like to much the idea of extension without a review, but as in this case we have already an interface (that could yet evolve a little bit) the C++0x accepted interface, I think that the review could be limited to see how the current C++0x interface can be use to get other higher functionalities, Howthis interface is implemented, review the docs and the tests. Of course we can find during the review something on the current C++0x interface and semantics that it is incorrect. Anthony has added the wait_for_all and wait_for_any that uses internal modification inthe future clasess. I would like to see if these functions can be implemented from outside. Otherwise, if we can not and if we consider that these functions are necessary, this mean IMHO that the standard is not enough open. But all the if need to be proved. My question now is if we can give the same kind of functionality to the end users with another interface. I'm working' on a wait_for_all and wait_for_any that takes functions as parameters that evaluates asynchronously and return a tuple of the returned values. See (http://www.nabble.com/Is-there-any-interest-in-Asynchronous-Executors-and-As...) These functions would only use the C++0x accepted interface. The advantage of taking functions is that we can wrap these function and do something before and after, in particular signaling when the function ends so no need in this case for callback (which do not mean that we don't need callbacks for other cases). With the Anthony proposal: boost::packaged_task<int> tsk1(simple_thread); boost::unique_future<int> fut1 = tsk1.get_future(); boost::thread th1(boost::move(tsk1)); boost::packaged_task<int> tsk2(simple_thread2); boost::unique_future<int> fut2 = tsk2.get_future(); boost::thread th2(boost::move(tsk2)); unsigned res = boost::wait_for_any(fut1, fut2); int val; switch (res) { case 0: val = fut1.get(); break; case 1: val = fut2.get(); break; } // use val with my not yet completly implemented interface just that: bith::shared_launcher ae; std::pair<unsigned,int> res = bith::wait_for_any(ae, simple_thread, simple_thread2); // use res.first for the future that has finished and res.second for the value. where bith::shared_launcher is an asynchonous executor (a thread pool can also be an asynchronous executor). I have in mind also other functions as fork_all, wait_all, get_all bith::shared_launcher ae; typedef bith::result_of::fork_all<bith::shared_launcher, fusion::tuple<int(*)(),int(*)()> >::type auto_type; auto_type tple = bith::fork_all(ae, simple_thread, simple_thread); typedef bith::result_of::get_all<auto_type>::type auto_get_all_type; auto_get_all_type res = bith::get_all(tple); fusion::for_each(res, print_xml()); with C++0X this can be writes as bith::shared_launcher ae; auto tple = bith::fork_all(ae, simple_thread, simple_thread); autho res = bith::get_all(tple); fusion::for_each(res, print_xml()); I you are interested I can share with you my current implementation. Best, Vicente

Tom Brinkman-2 wrote:
Is it more prudent to wait to find out what the c++ standards committe is going to do first, before adding a possibly incompatible version of the futures library to boost?
It would certainly be very unfortunate if the two implementations proved incompatible. OTOH, standardizing a library without having an existing well tested implementation is quite risky (look at std::string). In my understanding the C++ committee has very limited resources. I have no doubts that the committee members are very skilled and experienced programmers but there probably hasn't more than a few people involved in designing std.futures. A boost review and library can give them valuable feedback, that's the whole point of boost. Even though the experience from boost.futures might arrive too late to change the std.futures proposal it might allow them to remove std.futures and add it later on. I am personally very worried that Anthony's implementation has been too rushed and has had too much focus on being applicable to thread pools. See my review for more details. Tom Brinkman-2 wrote:
One could ask, if Anthony's submission is approved by the c++ standards committe, what is the point of adding a "futures" library to boost as well?
Another important point is that a boost library can be available years sooner than widespread C++ standard implementations will. Best Regards, Johan Torp www.johantorp.com -- View this message in context: http://www.nabble.com/Pondering-Futures-tp21359362p21387404.html Sent from the Boost - Dev mailing list archive at Nabble.com.
participants (8)
-
Anthony Williams
-
Beman Dawes
-
dherring@ll.mit.edu
-
Johan Torp
-
Mathias Gaunard
-
Oliver Seiler
-
Tom Brinkman
-
vicente.botet