
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 02 June 2008 13:02 pm, Peter Dimov wrote:
Frank Mori Hess:
Oh, my use case is the "lifting of an ordinary function to an asynchronous one that takes/returns future_value objects" I mentioned earlier in the post. To be more specific:
http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/ active_function.html
Hm.
It would be nice if you could provide a better motivating example. :-)
Well, I want the "lifted" versions of functions to be as useable as ordinary functions. So, you can compose functions whose types don't match exactly: float f(); void g(double x); g(f()); //fine But not the version lifted to future_handles: future_handle<float> lifted_f(); future_handle<void> lifted_g(future_handle<double> x); lifted_g(lifted_f()); // error, no implicit conversions for future_handle
That aside, I'm not sure why you need future_value semantics. Let's assume that one has a primitive
future<R> async( F f, A1 a1, ..., An an );
that schedules bind(f,a1,a2,...,an) for execution. It wouldn't be hard to make it recognize when Ai is future<Bi> and do the following instead:
async_with_guard(
bind( A1::ready, a1 ) && ...,
f,
bind( A1::get, a1 ), ... );
The 'guard' predicate is just symbolic since the scheduler would in reality store the futures as dependencies and use the appropriate "multi-multiwait". But the point is that I don't see the above requiring any future_value-specific operations.
That's interesting. The binds you describe in async_with_guard play a role similar to my future_combining_barrier(), except they need a scheduler thread to evaluate them, whereas the user functor passed to future_combining_barrier will be evaluated by whatever thread tries to use the returned future once its future dependencies are all ready. And as I realized and posted a couple hours ago, future_combining_barrier plus a future_handle would be sufficient for me to implement a future_value on top of. However, the William's future does not currently support any multi-multiwait. Its wait_for_all and wait_for_any do not return futures but block when called. The Gaskill futures do have operator|| and operator&& but they are not efficient enough to build a scheduler on. So, I'd like to see something like the future_select, future_barrier, future_selector, future_combining_barrier stuff I'm working on in libpoet in the boost futures library. None of them require a future_value.
It's not clear whether the goal of libpoet is to provide fine-grained parallelism or lazy evaluation;
active_function provides fine-grained parallelism. Or, maybe adjustable-grained, since multiple active_functions can share the same scheduler thread. Lazy evaluation can be achieved with future_combining_barrier (which isn't in the online docs or any release yet).
if the latter, one could expect all functions to take futures, since an active_function provides no fine-grained laziness. In this case the above "activize by default" approach won't be very convenient.
You can get fine-grained laziness by using future_select in conjunction with future_combining_barrier. For instance, if you wait on a future returned by future_select, and the inputs to the future select where created by future_combining_barrier, then it will only run the combiners of the input futures until the first one of them completes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFIRD7G5vihyNWuA4URAsXnAJ9T2L1HVs08S2lfw4DEbEKLuj5WrwCeKSI/ ECL+rJ1JKZQeUgRl0lmuZAw= =pw1w -----END PGP SIGNATURE-----