On 11/30/2016 08:10 AM, Biddiscombe, John A. wrote:
Christophe
I don't think the libraries have the same goals (or at least it seems to me so). Asynchronous is first of all an architecture tool focusing on organizing a whole application into thread worlds. <
If I understand this correctly, then I'd say that that is what HPX does too. (I usually explain to others that OpenMP creates 'parallel regions', where code operates in tasks, whereas the whole of an HPX application is one enormous parallel region). I presume this is what you mean by 'thread worlds' Not sure if I understand. Can you point me to some documentation or examples?
Disclaimer: my knowledge of HPX is limited to a quick glance at the doc. Feel free to correct my mistakes. I understood HPX as a library returning futures to calls to asynchronous functions, somewhat similar to std::async. In that case, the main region with all the futures would be a thread world for asynchronous. In huge applications, this does not solve the problem of organizing thousands of objects within threads.
The libraries also do not have the same design / tradeoffs. Asynchronous can make use of futures but encourages callbacks and tries to make these as safe as possible. The goal is to be as asynchronous (meaning non-blocking) as possible. <
A future .then() or continuation is really just a type of callback too (broadly speaking).
Not really, if I understand correctly (http://en.cppreference.com/w/cpp/experimental/future/then). The functor object passed to then() is executed in an unspecified thread of execution, which makes it hard for the caller to (safely) pass data which might or might not be valid or relevant at the time the then functor executes. I however could not find out whether this also applied to HPX. This simple example, called within a state machine living within a thread world will help me show the difference: post_callback( // task running in threadpool [](){/* long lasting task */}, // callback [this](boost::asynchronous::expected<void>) { // if this is called, it is guaranteed that: // this executes within the thread context of the calling object // the calling object is still alive //----> we now decide what to do next } ); As the callback executes within the calling object's thread context, we can choose at the callback execution time if we still want to call the code which we would call in the then(), and if we call, we do it with data relevant at this time, not at the time of the first call.
Future-based designs do not mix well with state machines' run-to-completion. <
Could you elaborate a little on that comment please? I have a had a couple of instances where I'm manipulating 'state' and transitioning from one to another - I would welcome some ideas on how to make this a bit cleaner.
A future.then() returns another future so isn't it just delaying the fact that I have to decide at some point what to do with the future object? Do I poll it, get() it or ignore it? Polling is tedious, ignore usually wrong, and get() means blocking. As a state machine run-to-completion is supposed to execute in no time, this is not a good option. Run-to-completion means: event is sent, transition is executed. Until it completes, the state machine is in an unstable state. This has to be kept as short as possible.
The reason for the non-blocking focus is that I'm using the library at work in an industrial 24/7 application. When working on the production line, blocking is a disaster. If an algorithm goes astray, or simply takes longer than usually, blocking the production line results in huge costs. Crashes due to races also. Asynchronous provides ways to avoid both. <
I would say that non-blocking behaviour is one of the central goals of HPX. Continuations are only triggered when futures become ready and therefore blocking is avoided - so I don't think there's any disagreement there! Races are a problem, but a functional style of programming goes a long way to avoiding them.
I agree that HPX likely solves well the race problem, which is a great achievement. I feel both libraries solve quite different problems. Asynchronous is focusing on organizing objects into threads and building everything else on top of that. In that context, callbacks within these object's thread contexts make more sense than a fire-and-forget of a future.then(); Which does not mean a fundamental disagreement with HPX, simply a different focus.
Thanks for the reply - I'll be going through your repo looking for good ideas (and borrowing them).
I'd love it! Thanks a lot for the feedback, I now see what things doc is missing (explanation of thread worlds, reasons for callbacks)
Cheers
JB
Cheers, Christophe