Expand description
Minimal data-parallel primitives over std::thread::scope (no external deps).
The thread count comes from FFDP_THREADS (if set) else available cores;
threads <= 1 falls back to a plain sequential map, so behaviour is
deterministic regardless of parallelism.
Two cost-control knobs keep parallelism a net win across problem sizes:
MIN_PAR: rounds with fewer than this many items run SERIALLY, so a tiny frontier (the common case on small problems, and the tail of large ones) never pays thread-spawn cost. Output is identical either way.MAX_DEFAULT_THREADS: the auto thread count is capped, because measured scaling plateaus by ~4 cores (Amdahl: serial successor-gen/dedup/heap); spawning one thread per core per round past that is pure overhead. An explicitFFDP_THREADSis honoured uncapped.
Constants§
- MIN_PAR
- Below this item count a round runs serially (spawning isn’t worth it).
Functions§
- num_
threads - Resolve the worker count:
FFDP_THREADSenv override (uncapped), elsemin(cores, MAX_DEFAULT_THREADS). - par_map
- Map
foveritemsacrossthreadsscoped workers, preserving input order. Each worker owns a contiguous chunk; results are concatenated in order, so the output is identical to a sequential map (only the cost is parallel). - par_
map_ with - Like
par_map, but each worker first builds a privatestateviainit(e.g. reusable scratch buffers) and threads it throughf, so per-item allocation is amortised across a chunk. Output order matches input.