Functions | |
| impl::async_wr | rangeless::fn::to_async (size_t queue_size=16) |
Wrap generating seq in an async-task. More... | |
| template<typename F > | |
| impl::par_transform< F, impl::std_async > | rangeless::fn::transform_in_parallel (F map_fn) |
Parallelized version of fn::transform More... | |
| template<typename F , typename Async > | |
| impl::par_transform< F, Async > | rangeless::fn::transform_in_parallel (F map_fn, Async async) |
A version of transform_in_parallel that uses a user-provided Async (e.g. backed by a fancy work-stealing thread-pool implementation). More... | |
|
inline |
Wrap generating seq in an async-task.
| impl::par_transform<F, impl::std_async> rangeless::fn::transform_in_parallel | ( | F | map_fn | ) |
Parallelized version of fn::transform
Requires #define RANGELESS_FN_ENABLE_PARALLEL 1 before #include fn.hpp because it brings in "heavy" STL #includes (<future> and <thread>).
queue_capacity is the maximum number of simultaneosly-running std::async-tasks, each executing a single invocation of map_fn.
NB: if the execution time of map_fn is highly variable, having higher capacity may help, such that tasks continue to execute while we're blocked waiting on a result from a long-running task.
NB: If the tasks are too small compared to overhead of running as async-task, it may be helpful to batch them (see fn::in_groups_of), have map_fn produce a vector of outputs from a vector of inputs, and fn::concat the outputs.
map_fn is required to be thread-safe.
NB: the body of the map_fn would normally compute the result in-place, but it could also, for example, execute a subprocess do it, or offload it to a cloud or a compute-farm, etc.
Q: Why do we need this? We have parallel std::transform and std::transform_reduce in c++17?
A: Parallel std::transform requires a multi-pass ForwardRange rather than InputRange, and std::terminates if any of the tasks throws. std::transform_reduce requires ForwardRange and type-symmetric, associative, and commutative BinaryOp (making it next-to-useless).
| impl::par_transform<F, Async> rangeless::fn::transform_in_parallel | ( | F | map_fn, |
| Async | async | ||
| ) |
A version of transform_in_parallel that uses a user-provided Async (e.g. backed by a fancy work-stealing thread-pool implementation).
Async is a unary invokable having the following signature: template<typename NullaryInvokable> operator()(NullaryInvokable job) const -> std::future<decltype(job())>
NB: Async must be copy-constructible (may be passed via std::ref as appropriate).
A single-thread pool can be used to offload the transform-stage to a separate thread if transform is not parallelizeable.