#![cfg(feature = "parallel")]
use std::thread;
pub(crate) fn parallel_index_map(
n: usize,
overlap: usize,
out: &mut [f64],
worker: impl Fn(usize, usize) -> Vec<f64> + Sync,
) {
let ncpus = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
if ncpus <= 1 || n < 8192 {
let full = worker(0, n);
out.copy_from_slice(&full);
return;
}
let chunk = (n + ncpus - 1) / ncpus;
let mut specs: Vec<(usize, usize, usize)> = Vec::new();
for c in 0..ncpus {
let cs = c * chunk;
let ce = ((c + 1) * chunk).min(n);
if cs >= ce {
continue;
}
let start = if c == 0 { 0 } else { cs.saturating_sub(overlap) };
specs.push((cs, ce, start));
}
let results: Vec<(usize, usize, usize, Vec<f64>)> = thread::scope(|s| {
let mut handles = Vec::with_capacity(specs.len());
for (cs, ce, start) in specs {
let w = &worker;
let h = s.spawn(move || {
let local = w(start, ce);
(cs, ce, start, local)
});
handles.push(h);
}
handles
.into_iter()
.map(|h| h.join().unwrap())
.collect()
});
for (cs, ce, start, local) in results {
let owned = &local[(cs - start)..(ce - start)];
out[cs..ce].copy_from_slice(owned);
}
}
pub(crate) fn parallel_index_map_2(
n: usize,
overlap: usize,
out_a: &mut [f64],
out_b: &mut [f64],
worker: impl Fn(usize, usize) -> (Vec<f64>, Vec<f64>) + Sync,
) {
let ncpus = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
if ncpus <= 1 || n < 8192 {
let (a, b) = worker(0, n);
out_a.copy_from_slice(&a);
out_b.copy_from_slice(&b);
return;
}
let chunk = (n + ncpus - 1) / ncpus;
let mut specs: Vec<(usize, usize, usize)> = Vec::new();
for c in 0..ncpus {
let cs = c * chunk;
let ce = ((c + 1) * chunk).min(n);
if cs >= ce {
continue;
}
let start = if c == 0 { 0 } else { cs.saturating_sub(overlap) };
specs.push((cs, ce, start));
}
let results: Vec<(usize, usize, usize, Vec<f64>, Vec<f64>)> = thread::scope(|s| {
let mut handles = Vec::with_capacity(specs.len());
for (cs, ce, start) in specs {
let w = &worker;
let h = s.spawn(move || {
let (a, b) = w(start, ce);
(cs, ce, start, a, b)
});
handles.push(h);
}
handles
.into_iter()
.map(|h| h.join().unwrap())
.collect()
});
for (cs, ce, start, a, b) in results {
out_a[cs..ce].copy_from_slice(&a[(cs - start)..(ce - start)]);
out_b[cs..ce].copy_from_slice(&b[(cs - start)..(ce - start)]);
}
}