Eager parallel map. The eagerness of this function means it has less
overhead than the lazily evaluated TaskPool.map and should be
preferred where the memory requirements of eagerness are acceptable.
functions are the functions to be evaluated, passed as template
alias parameters in a style similar to
std.algorithm.iteration.map.
The first argument must be a random access range. For performance
reasons, amap will assume the range elements have not yet been
initialized. Elements will be overwritten without calling a destructor
nor doing an assignment. As such, the range must not contain meaningful
data: either un-initialized objects, or
objects in their .init state.
autonumbers = iota(100_000_000.0);
// Find the square roots of numbers.//// Timings on an Athlon 64 X2 dual core machine://// Parallel eager map: 0.802 s// Equivalent serial implementation: 1.768 sautosquareRoots = taskPool.amap!sqrt(numbers);
Immediately after the range argument, an optional work unit size argument
may be provided. Work units as used by amap are identical to those
defined for parallel foreach. If no work unit size is provided, the
default work unit size is used.
// Same thing, but make work unit size 100.autosquareRoots = taskPool.amap!sqrt(numbers, 100);
An output range for returning the results may be provided as the last
argument. If one is not provided, an array of the proper type will be
allocated on the garbage collected heap. If one is provided, it must be a
random access range with assignable elements, must have reference
semantics with respect to assignment to its elements, and must have the
same length as the input range. Writing to adjacent elements from
different threads must be safe.
// Same thing, but explicitly allocate an array// to return the results in. The element type// of the array may be either the exact type// returned by functions or an implicit conversion// target.autosquareRoots = newfloat[numbers.length];
taskPool.amap!sqrt(numbers, squareRoots);
// Multiple functions, explicit output range, and// explicit work unit size.autoresults = newTuple!(float, real)[numbers.length];
taskPool.amap!(sqrt, log)(numbers, 100, results);
Note:
A memory barrier is guaranteed to be executed after all results are written
but before returning so that results produced by all threads are visible
in the calling thread.
Tips:
To perform the mapping operation in place, provide the same range for the
input and output range.
To parallelize the copying of a range with expensive to evaluate elements
to an array, pass an identity function (a function that just returns
whatever argument is provided to it) to amap.
Exception Handling:
When at least one exception is thrown from inside the map functions,
the submission of additional Task objects is terminated as soon as
possible, in a non-deterministic manner. All currently executing or
enqueued work units are allowed to complete. Then, all exceptions that
were thrown from any work unit are chained using Throwable.next and
rethrown. The order of the exception chaining is non-deterministic.
Eager parallel map. The eagerness of this function means it has less overhead than the lazily evaluated TaskPool.map and should be preferred where the memory requirements of eagerness are acceptable. functions are the functions to be evaluated, passed as template alias parameters in a style similar to std.algorithm.iteration.map. The first argument must be a random access range. For performance reasons, amap will assume the range elements have not yet been initialized. Elements will be overwritten without calling a destructor nor doing an assignment. As such, the range must not contain meaningful data: either un-initialized objects, or objects in their .init state.
Immediately after the range argument, an optional work unit size argument may be provided. Work units as used by amap are identical to those defined for parallel foreach. If no work unit size is provided, the default work unit size is used.
An output range for returning the results may be provided as the last argument. If one is not provided, an array of the proper type will be allocated on the garbage collected heap. If one is provided, it must be a random access range with assignable elements, must have reference semantics with respect to assignment to its elements, and must have the same length as the input range. Writing to adjacent elements from different threads must be safe.
Note:
A memory barrier is guaranteed to be executed after all results are written but before returning so that results produced by all threads are visible in the calling thread.
Tips:
To perform the mapping operation in place, provide the same range for the input and output range.
To parallelize the copying of a range with expensive to evaluate elements to an array, pass an identity function (a function that just returns whatever argument is provided to it) to amap.
Exception Handling:
When at least one exception is thrown from inside the map functions, the submission of additional Task objects is terminated as soon as possible, in a non-deterministic manner. All currently executing or enqueued work units are allowed to complete. Then, all exceptions that were thrown from any work unit are chained using Throwable.next and rethrown. The order of the exception chaining is non-deterministic.