Parallel loops and binary splitting
Two generic helpers distribute work over the threads of the pool (The thread pool): flint_parallel_do runs independent calls , and flint_parallel_binary_splitting runs the two halves of a binary splitting recursion in parallel.
Static scheduling of a loop#
flint_parallel_do evaluates with threads, where is the number of workers obtained plus the calling thread. The indices are divided once, before the threads start; there is no work stealing. Two schedules are available.
Blocks (FLINT_PARALLEL_UNIFORM): with , thread gets the indices . When all calls cost the same, the loads differ by at most calls, and each thread works on a contiguous range, which is good for memory locality.
Strides (FLINT_PARALLEL_STRIDED): thread gets the indices . This is the better choice when the cost of call varies monotonically, as it does when indexes coefficients or subproblems of increasing size.
Theorem 1 (Balance of strided scheduling). Let and let be the load of thread under strided scheduling. Then for all .
Proof. Let and let and be the numbers of indices of the two threads. The index sets are and , and because .
Since , monotonicity gives for . Hence .
Since , also whenever . If , summing over gives . If , the same sum covers all but the last index of thread , so . The case of nonincreasing costs is symmetric.
With blocks, monotone costs can make the imbalance as large as , roughly the difference between the first and last block.
The flag FLINT_PARALLEL_DYNAMIC is reserved for dynamic scheduling, in which threads take new indices from a shared counter as they finish. It is not implemented and currently gives blocks.
Parallel binary splitting#
Binary splitting evaluates as with , recursing until is at most a cutoff [HP1998; Ber2008]. The two recursive calls are independent, so the recursion tree has natural parallelism near its root.
Input: a range , a cutoff and a thread budget (thread_limit, or flint_get_num_threads() if not positive).
- If , compute with the base case and return.
- Request one worker, subject to the caller's own budget.
- If one was obtained: wake it on with budget , lower the caller's budget to and compute , then restore the budget and wait for the worker.
- Otherwise compute and one after the other.
- Return the merge of the two results.
Each level halves the budget, so with threads the top levels of the tree run in parallel and every thread then works on one subtree of size about . The two recursive calls receive their shares as thread_limit, so no more than threads run base cases at the same time. For products whose operands grow along the recursion, most of the time is spent in the last merges near the root, so the speedup of binary splitting by itself is limited; it is most effective when the merge operation, typically a large multiplication, is itself parallel.
void flint_parallel_do(do_func_t f, void * args, slong n, int thread_limit, int flags)void flint_parallel_binary_splitting(void * res, bsplit_basecase_func_t basecase, bsplit_merge_func_t merge, size_t sizeof_res, bsplit_init_func_t init, bsplit_clear_func_t clear, void * args, slong a, slong b, slong basecase_cutoff, int thread_limit, int flags)Referenced from#
References#
- [HP1998] B. Haible and T. Papanikolaou, "Fast multiprecision evaluation of series of rational numbers", Algorithmic Number Theory (ANTS-III), LNCS 1423 (1998), 338–350
- [Ber2008] D. J. Bernstein, "Fast multiplication and its applications", in Algorithmic Number Theory, MSRI Publications 44 (2008), 325–384
The FLINT team, “Parallel loops and binary splitting,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/parallel/parallel-loops.html (generated 2026-11-02).
@misc{flint-doc-algorithms-parallel-parallel-loops,
author = {{The FLINT team}},
title = {{Parallel loops and binary splitting}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/parallel/parallel-loops.html},
note = {Generated 2026-11-02}
}