src/parallelism.rs

Wed, 22 Apr 2026 23:41:59 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 22 Apr 2026 23:41:59 -0500
branch
dev
changeset 197
1f301affeae3
parent 45
ad1f3705c3fc
permissions
-rw-r--r--

Fix internal links in documentation

8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Parallel computing helper routines.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 It mains the number of threads to use, a thread pool, and provides a budgeting tool
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 to limit the number of threads spawned in recursive computations.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 For actually spawning scoped tasks in a thread pool, it currently uses [`rayon`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 */
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
10 pub use rayon::{Scope, ThreadPool, ThreadPoolBuilder};
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 use std::num::NonZeroUsize;
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 use std::sync::atomic::{
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 AtomicUsize,
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
14 Ordering::{Relaxed, Release},
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 };
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
16 use std::sync::Once;
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
17 use std::thread::available_parallelism;
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
19 #[cfg(feature = "use_custom_thread_pool")]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 type Pool = ThreadPool;
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
21 #[cfg(not(feature = "use_custom_thread_pool"))]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 type Pool = GlobalPool;
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
24 const ONE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(1) };
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
25 static mut TASK_OVERBUDGETING: AtomicUsize = AtomicUsize::new(1);
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
26 static mut N_THREADS: NonZeroUsize = ONE;
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
27 static mut POOL: Option<Pool> = None;
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 static INIT: Once = Once::new();
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
30 #[cfg(not(feature = "use_custom_thread_pool"))]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 mod global_pool {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 /// This is a nicer way to use the global pool of [`rayon`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 pub struct GlobalPool;
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
35 #[cfg(not(feature = "use_custom_thread_pool"))]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 impl GlobalPool {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 #[inline]
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 pub fn scope<'scope, OP, R>(&self, op: OP) -> R
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 where
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 OP: FnOnce(&rayon::Scope<'scope>) -> R + Send,
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
41 R: Send,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
42 {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 rayon::scope(op)
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
48 #[cfg(not(feature = "use_custom_thread_pool"))]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 pub use global_pool::GlobalPool;
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 /// Set the number of threads.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 /// This routine can only be called once.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 /// It also calls [`set_task_overbudgeting`] with $m = (n + 1) / 2$.
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
55 pub fn set_num_threads(n: NonZeroUsize) {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 INIT.call_once(|| unsafe {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 N_THREADS = n;
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 let n = n.get();
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 set_task_overbudgeting((n + 1) / 2);
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 POOL = if n > 1 {
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
61 #[cfg(feature = "use_custom_thread_pool")]
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
62 {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 Some(ThreadPoolBuilder::new().num_threads(n).build().unwrap())
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 }
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
65 #[cfg(not(feature = "use_custom_thread_pool"))]
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
66 {
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
67 ThreadPoolBuilder::new()
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
68 .num_threads(n)
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
69 .build_global()
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
70 .unwrap();
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 Some(GlobalPool)
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 } else {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 None
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 });
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 /// Set overbudgeting count for [`TaskBudget`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 /// The initial value is 1. Calling [`set_num_threads`] sets this to $m = (n + 1) / 2$, where
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 /// $n$ is the number of threads.
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
83 pub fn set_task_overbudgeting(m: usize) {
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
84 #[allow(static_mut_refs)]
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
85 unsafe {
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
86 TASK_OVERBUDGETING.store(m, Relaxed)
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
87 }
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 /// Set the number of threads to the minimum of `n` and [`available_parallelism`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 /// This routine can only be called once.
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
93 pub fn set_max_threads(n: NonZeroUsize) {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 let available = available_parallelism().unwrap_or(ONE);
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 set_num_threads(available.min(n));
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 /// Get the number of threads
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 pub fn num_threads() -> NonZeroUsize {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 unsafe { N_THREADS }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 /// Get the thread pool.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 /// If the number of configured threads is less than 2, this is None.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 /// The pool has [`num_threads`]` - 1` threads.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 pub fn thread_pool() -> Option<&'static Pool> {
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
108 #[allow(static_mut_refs)]
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
109 unsafe {
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
110 POOL.as_ref()
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
111 }
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 /// Get the number of thread pool workers.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 /// This is [`num_threads`]` - 1`.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 pub fn thread_pool_size() -> usize {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 unsafe { N_THREADS }.get() - 1
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 /// Thread budgeting tool.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 /// This allows limiting the number of tasks inserted into the queue in nested computations.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 /// Otherwise it wraps [`rayon`] when not single-threaded.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 pub enum TaskBudget<'scope, 'scheduler> {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 /// No threading performed.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 SingleThreaded,
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 /// Initial multi-threaded state
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 MultiThreadedInitial {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 /// Thread budget counter
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
131 budget: AtomicUsize,
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 /// Thread pool
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
133 pool: &'scheduler Pool,
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 },
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 /// Nested multi-threaded state
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 MultiThreadedZoom {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 /// Thread budget reference
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
138 budget: &'scope AtomicUsize,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
139 scope: &'scheduler Scope<'scope>,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
140 },
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 /// Task execution scope for [`TaskBudget`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 pub enum TaskBudgetScope<'scope, 'scheduler> {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 SingleThreaded,
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 MultiThreaded {
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
147 budget: &'scope AtomicUsize,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
148 scope: &'scheduler Scope<'scope>,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
149 },
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 impl<'scope, 'b> TaskBudget<'scope, 'b> {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 /// Initialise a task budget in the main thread pool.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 ///
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 /// The number of tasks [executed][TaskBudgetScope::execute] in [scopes][TaskBudget::zoom]
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 /// created through the budget is limited to [`num_threads()`]` + overbudget`. If `overbudget`
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 /// is `None`, the [global setting][set_task_overbudgeting] is used.ยง
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
158 pub fn init(overbudget: Option<usize>) -> Self {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159 let n = num_threads().get();
45
ad1f3705c3fc Updates for current nightly rust
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
160 #[allow(static_mut_refs)]
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 let m = overbudget.unwrap_or_else(|| unsafe { TASK_OVERBUDGETING.load(Relaxed) });
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 if n <= 1 {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 Self::SingleThreaded
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 } else if let Some(pool) = thread_pool() {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 let budget = AtomicUsize::new(n + m);
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 Self::MultiThreadedInitial { budget, pool }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 } else {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168 Self::SingleThreaded
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 /// Initialise single-threaded thread budgeting.
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
173 pub fn none() -> Self {
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
174 Self::SingleThreaded
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
175 }
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 impl<'scope, 'scheduler> TaskBudget<'scope, 'scheduler> {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 /// Create a sub-scope for launching tasks
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
180 pub fn zoom<'smaller, F, R: Send>(&self, scheduler: F) -> R
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
181 where
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
182 'scope: 'smaller,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
183 F: for<'a> FnOnce(TaskBudgetScope<'smaller, 'a>) -> R + Send + 'smaller,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
184 {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 match self {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 &Self::SingleThreaded => scheduler(TaskBudgetScope::SingleThreaded),
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187 &Self::MultiThreadedInitial { ref budget, pool } => {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 let budget_ref = unsafe {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 // Safe: scheduler is dropped when 'smaller becomes invalid.
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 std::mem::transmute::<&AtomicUsize, &'smaller AtomicUsize>(budget)
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 };
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 pool.scope(move |scope| {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
193 scheduler(TaskBudgetScope::MultiThreaded { scope, budget: budget_ref })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194 })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195 },
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
196 &Self::MultiThreadedZoom { budget, .. /* scope */ } => {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
197 rayon::scope(move |scope| {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
198 scheduler(TaskBudgetScope::MultiThreaded { scope, budget })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
199 })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200 },
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
202 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
203 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
204
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 impl<'scope, 'scheduler> TaskBudgetScope<'scope, 'scheduler> {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
206 /// Queue a task or execute it in this thread if the thread budget is exhausted.
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
207 pub fn execute<F>(&self, job: F)
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
208 where
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
209 F: for<'b> FnOnce(TaskBudget<'scope, 'b>) + Send + 'scope,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
210 {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 match self {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 Self::SingleThreaded => job(TaskBudget::SingleThreaded),
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 Self::MultiThreaded { scope, budget } => {
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
214 let spawn = budget
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
215 .fetch_update(Release, Relaxed, |n| (n > 1).then_some(n - 1))
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
216 .is_ok();
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
217 if spawn {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 scope.spawn(|scope| {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 let task_budget = TaskBudget::MultiThreadedZoom { scope, budget };
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 job(task_budget);
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 budget.fetch_add(1, Release);
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
222 })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 } else {
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
224 job(TaskBudget::MultiThreadedZoom { scope, budget })
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
226 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
227 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
228 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 }
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 /// Runs `scheduler` with a [`TaskBudget`].
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
232 ///
197
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
233 /// This corresponds to calling `scheduler` with [`TaskBudget::init`]`(None)`.
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
234 pub fn with_task_budget<'scope, F, R>(scheduler: F) -> R
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
235 where
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
236 F: for<'b> FnOnce(TaskBudget<'scope, 'b>) -> R + 'scope,
1f301affeae3 Fix internal links in documentation
Tuomo Valkonen <tuomov@iki.fi>
parents: 45
diff changeset
237 {
8
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238 scheduler(TaskBudget::init(None))
4e09b7829b51 Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 }

mercurial