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 #include
s (<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::terminate
s 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.