Skip to content

Commit 3600ae6

Browse files
RecycledVec for par_iter_bp_delayed
1 parent e5b8a03 commit 3600ae6

1 file changed

Lines changed: 40 additions & 19 deletions

File tree

src/packed_seq.rs

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,36 @@ use super::*;
99

1010
type SimdBuf = [S; 8];
1111

12+
struct RecycledBox(Option<Box<SimdBuf>>);
13+
1214
thread_local! {
13-
static IT_BUF: RefCell<Vec<Box<SimdBuf>>> = {
15+
static RECYCLED_BOX_CACHE: RefCell<Vec<Box<SimdBuf>>> = {
1416
RefCell::new(vec![Box::new(SimdBuf::default())])
1517
};
1618
}
1719

18-
struct RecycledBox(Option<Box<SimdBuf>>);
19-
2020
impl RecycledBox {
2121
#[inline(always)]
22-
pub fn init_if_needed(&mut self) {
22+
fn take() -> Self {
23+
let mut buf = RECYCLED_BOX_CACHE.with_borrow_mut(|v| RecycledBox(v.pop()));
24+
buf.init_if_needed();
25+
buf
26+
}
27+
28+
#[inline(always)]
29+
fn init_if_needed(&mut self) {
2330
if self.0.is_none() {
2431
self.0 = Some(Box::new(SimdBuf::default()));
2532
}
2633
}
2734

2835
#[inline(always)]
29-
pub fn get(&self) -> &SimdBuf {
36+
fn get(&self) -> &SimdBuf {
3037
unsafe { self.0.as_ref().unwrap_unchecked() }
3138
}
3239

3340
#[inline(always)]
34-
pub fn get_mut(&mut self) -> &mut SimdBuf {
41+
fn get_mut(&mut self) -> &mut SimdBuf {
3542
unsafe { self.0.as_mut().unwrap_unchecked() }
3643
}
3744
}
@@ -56,26 +63,44 @@ impl Drop for RecycledBox {
5663
fn drop(&mut self) {
5764
let mut x = None;
5865
core::mem::swap(&mut x, &mut self.0);
59-
IT_BUF.with_borrow_mut(|v| v.push(unsafe { x.unwrap_unchecked() }));
66+
RECYCLED_BOX_CACHE.with_borrow_mut(|v| v.push(unsafe { x.unwrap_unchecked() }));
6067
}
6168
}
6269

63-
#[derive(Default)]
64-
struct SimdVec(Vec<S>);
70+
struct RecycledVec(Vec<S>);
6571

66-
impl Deref for SimdVec {
72+
thread_local! {
73+
static RECYCLED_VEC_CACHE: RefCell<Vec<Vec<S>>> = {
74+
RefCell::new(vec![])
75+
};
76+
}
77+
78+
impl RecycledVec {
79+
#[inline(always)]
80+
fn take() -> Self {
81+
RecycledVec(RECYCLED_VEC_CACHE.with_borrow_mut(|v| v.pop().unwrap_or_default()))
82+
}
83+
}
84+
85+
impl Deref for RecycledVec {
6786
type Target = Vec<S>;
6887
#[inline(always)]
6988
fn deref(&self) -> &Self::Target {
7089
&self.0
7190
}
7291
}
73-
impl DerefMut for SimdVec {
92+
impl DerefMut for RecycledVec {
7493
#[inline(always)]
7594
fn deref_mut(&mut self) -> &mut Self::Target {
7695
&mut self.0
7796
}
7897
}
98+
impl Drop for RecycledVec {
99+
#[inline(always)]
100+
fn drop(&mut self) {
101+
RECYCLED_VEC_CACHE.with_borrow_mut(|v| v.push(std::mem::take(&mut self.0)));
102+
}
103+
}
79104

80105
#[doc(hidden)]
81106
pub struct Bits<const B: usize>;
@@ -528,11 +553,7 @@ where
528553

529554
#[inline(always)]
530555
fn par_iter_bp(self, context: usize) -> PaddedIt<impl ChunkIt<S>> {
531-
// Boxed, so it doesn't consume precious registers.
532-
// Without this, cur is not always inlined into a register.
533-
let mut buf = IT_BUF.with_borrow_mut(|v| RecycledBox(v.pop()));
534-
buf.init_if_needed();
535-
self.par_iter_bp_with_buf(context, buf)
556+
self.par_iter_bp_with_buf(context, RecycledBox::take())
536557
}
537558

538559
#[inline(always)]
@@ -554,7 +575,7 @@ where
554575
delay1,
555576
delay2,
556577
1,
557-
SimdVec::default(),
578+
RecycledVec::take(),
558579
)
559580
}
560581

@@ -673,7 +694,7 @@ where
673694
delay: Delay,
674695
factor: usize,
675696
) -> PaddedIt<impl ChunkIt<(S, S)> + use<'s, B>> {
676-
self.par_iter_bp_delayed_with_factor_and_buf(context, delay, factor, SimdVec::default())
697+
self.par_iter_bp_delayed_with_factor_and_buf(context, delay, factor, RecycledVec::take())
677698
}
678699

679700
#[inline(always)]
@@ -822,7 +843,7 @@ where
822843
delay1,
823844
delay2,
824845
factor,
825-
SimdVec::default(),
846+
RecycledVec::take(),
826847
)
827848
}
828849

0 commit comments

Comments
 (0)