@@ -9,29 +9,36 @@ use super::*;
99
1010type SimdBuf = [ S ; 8 ] ;
1111
12+ struct RecycledBox ( Option < Box < SimdBuf > > ) ;
13+
1214thread_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-
2020impl 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) ]
81106pub 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