5656//! ## Performance
5757//!
5858//! run `cargo bench` to see the benchmarks on your device.
59- //! Benchmarks in author's environment show that this library has the advantage at `u16x8`
60- //! among the bitvector libraries currently implemented based on SIMD.
61- //! In addition, any SIMD bitvector implementation is inferior to [bit-vec](https://docs.rs/bit-vec/) in `creation`,
62- //! while this library performs relatively well overall.
6359
6460#![ feature( portable_simd) ]
6561#![ no_std]
@@ -96,7 +92,7 @@ pub type BitVec = BitVecSimd<[u64x4; 4], 4>;
9692pub struct BitVecSimd < A , const L : usize >
9793where
9894 A : Array + Index < usize > ,
99- A :: Item : BitContainer < L > ,
95+ A :: Item : BitBlock < L > ,
10096{
10197 // internal representation of bitvec
10298 // TODO: try `Vec`, may be better than smallvec
@@ -147,7 +143,7 @@ macro_rules! impl_operation {
147143impl < A , const L : usize > BitVecSimd < A , L >
148144where
149145 A : Array + Index < usize > ,
150- A :: Item : BitContainer < L > ,
146+ A :: Item : BitBlock < L > ,
151147{
152148 // convert total bit to length
153149 // input: Number of bits
@@ -173,9 +169,9 @@ where
173169 #[ inline]
174170 fn set_bit (
175171 flag : bool ,
176- bytes : <A :: Item as BitContainer < L > >:: Element ,
172+ bytes : <A :: Item as BitBlock < L > >:: Item ,
177173 offset : u32 ,
178- ) -> <A :: Item as BitContainer < L > >:: Element {
174+ ) -> <A :: Item as BitBlock < L > >:: Item {
179175 match flag {
180176 true => bytes | A :: Item :: ONE_ELEMENT . wrapping_shl ( offset) ,
181177 false => bytes & !A :: Item :: ONE_ELEMENT . wrapping_shl ( offset) ,
@@ -293,7 +289,7 @@ where
293289 /// assert_eq!(bitvec.get(2), Some(false));
294290 /// assert_eq!(bitvec.get(3), None);
295291 /// ```
296- pub fn from_slice_copy ( slice : & [ <A :: Item as BitContainer < L > >:: Element ] , nbits : usize ) -> Self {
292+ pub fn from_slice_copy ( slice : & [ <A :: Item as BitBlock < L > >:: Item ] , nbits : usize ) -> Self {
297293 let len = ( nbits + A :: Item :: ELEMENT_BIT_WIDTH - 1 ) / A :: Item :: ELEMENT_BIT_WIDTH ;
298294 assert ! ( len <= slice. len( ) ) ;
299295
@@ -334,7 +330,7 @@ where
334330 /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
335331 ///
336332 pub unsafe fn from_raw_copy (
337- ptr : * const <A :: Item as BitContainer < L > >:: Element ,
333+ ptr : * const <A :: Item as BitBlock < L > >:: Item ,
338334 buffer_len : usize ,
339335 nbits : usize ,
340336 ) -> Self {
@@ -409,11 +405,7 @@ where
409405 self . storage . spilled ( )
410406 }
411407
412- fn clear_arr_high_bits (
413- arr : & mut [ <A :: Item as BitContainer < L > >:: Element ] ,
414- bytes : usize ,
415- bits : usize ,
416- ) {
408+ fn clear_arr_high_bits ( arr : & mut [ <A :: Item as BitBlock < L > >:: Item ] , bytes : usize , bits : usize ) {
417409 let mut end_bytes = bytes;
418410 if bits > 0 {
419411 arr[ end_bytes] =
@@ -426,7 +418,7 @@ where
426418 }
427419
428420 fn fill_arr_high_bits (
429- arr : & mut [ <A :: Item as BitContainer < L > >:: Element ] ,
421+ arr : & mut [ <A :: Item as BitBlock < L > >:: Item ] ,
430422 bytes : usize ,
431423 bits : usize ,
432424 bytes_max : usize ,
@@ -947,7 +939,7 @@ where
947939impl < A , I : Iterator < Item = bool > , const L : usize > From < I > for BitVecSimd < A , L >
948940where
949941 A : Array + Index < usize > ,
950- A :: Item : BitContainer < L > ,
942+ A :: Item : BitBlock < L > ,
951943{
952944 fn from ( i : I ) -> Self {
953945 Self :: from_bool_iterator ( i)
@@ -964,7 +956,7 @@ macro_rules! impl_trait {
964956 impl <A , const L : usize > $( $name ) + for $( $name1 ) +
965957 where
966958 A : Array + Index <usize >,
967- A :: Item : BitContainer <L >,
959+ A :: Item : BitBlock <L >,
968960 { $( $body ) * }
969961 } ;
970962}
@@ -1123,8 +1115,8 @@ impl_trait! {(BitXorAssign), (BitVecSimd<A, L>), { impl_bit_assign_fn!((Self), b
11231115impl_trait ! { ( BitXorAssign < & BitVecSimd <A , L > >) , ( BitVecSimd <A , L >) , { impl_bit_assign_fn!( ( & BitVecSimd <A , L >) , bitxor_assign, xor_inplace) ; } }
11241116impl_trait ! { ( BitXorAssign < & mut BitVecSimd <A , L > >) , ( BitVecSimd <A , L >) , { impl_bit_assign_fn!( ( & mut BitVecSimd <A , L >) , bitxor_assign, xor_inplace) ; } }
11251117
1126- // BitContainerItem is the element of a SIMD type BitContainer
1127- pub trait BitContainerItem :
1118+ // BitBlockItem is the element of a SIMD type BitBlock
1119+ pub trait BitBlockItem :
11281120 Not < Output = Self >
11291121 + BitAnd < Output = Self >
11301122 + BitOr < Output = Self >
@@ -1154,9 +1146,9 @@ pub trait BitContainerItem:
11541146 fn clear_low_bits ( self , rhs : u32 ) -> Self ;
11551147}
11561148
1157- macro_rules! impl_bitcontaineritem {
1149+ macro_rules! impl_bitblock_item {
11581150 ( $type: ty, $zero: expr, $one: expr, $max: expr) => {
1159- impl BitContainerItem for $type {
1151+ impl BitBlockItem for $type {
11601152 const BIT_WIDTH : usize = Self :: BITS as usize ;
11611153 const ZERO : Self = $zero;
11621154 const ONE : Self = $one;
@@ -1195,14 +1187,14 @@ macro_rules! impl_bitcontaineritem {
11951187 } ;
11961188}
11971189
1198- impl_bitcontaineritem ! ( u8 , 0u8 , 1u8 , 0xFFu8 ) ;
1199- impl_bitcontaineritem ! ( u16 , 0u16 , 1u16 , 0xFFFFu16 ) ;
1200- impl_bitcontaineritem ! ( u32 , 0u32 , 1u32 , 0xFFFFFFFFu32 ) ;
1201- impl_bitcontaineritem ! ( u64 , 0u64 , 1u64 , 0xFFFFFFFFFFFFFFFFu64 ) ;
1190+ impl_bitblock_item ! ( u8 , 0u8 , 1u8 , 0xFFu8 ) ;
1191+ impl_bitblock_item ! ( u16 , 0u16 , 1u16 , 0xFFFFu16 ) ;
1192+ impl_bitblock_item ! ( u32 , 0u32 , 1u32 , 0xFFFFFFFFu32 ) ;
1193+ impl_bitblock_item ! ( u64 , 0u64 , 1u64 , 0xFFFFFFFFFFFFFFFFu64 ) ;
12021194
1203- // BitContainer is the basic building block for internal storage
1195+ // BitBlock is the basic building block for internal storage
12041196// BitVec is expected to be aligned properly
1205- pub trait BitContainer < const L : usize > :
1197+ pub trait BitBlock < const L : usize > :
12061198 Not < Output = Self >
12071199 + BitAnd < Output = Self >
12081200 + BitOr < Output = Self >
@@ -1214,38 +1206,38 @@ pub trait BitContainer<const L: usize>:
12141206 + Copy
12151207 + Clone
12161208 + Debug
1217- + From < [ Self :: Element ; L ] >
1209+ + From < [ Self :: Item ; L ] >
12181210{
1219- type Element : BitContainerItem ;
1211+ type Item : BitBlockItem ;
12201212 const BIT_WIDTH : usize ;
12211213 const ELEMENT_BIT_WIDTH : usize ;
12221214 const LANES : usize ;
1223- const ZERO_ELEMENT : Self :: Element ;
1224- const ONE_ELEMENT : Self :: Element ;
1225- const MAX_ELEMENT : Self :: Element ;
1215+ const ZERO_ELEMENT : Self :: Item ;
1216+ const ONE_ELEMENT : Self :: Item ;
1217+ const MAX_ELEMENT : Self :: Item ;
12261218 const ZERO : Self ;
12271219 const MAX : Self ;
1228- fn to_array ( self ) -> [ Self :: Element ; L ] ;
1220+ fn to_array ( self ) -> [ Self :: Item ; L ] ;
12291221 fn and_inplace ( & mut self , rhs : & Self ) ;
12301222 fn or_inplace ( & mut self , rhs : & Self ) ;
12311223 fn xor_inplace ( & mut self , rhs : & Self ) ;
12321224}
12331225
1234- macro_rules! impl_bitcontainer {
1235- ( $type: ty, $elem_type : ty, $lanes: expr) => {
1236- impl BitContainer <$lanes> for $type {
1237- type Element = $elem_type ;
1238- const BIT_WIDTH : usize = ( $lanes * <$elem_type >:: BIT_WIDTH ) as usize ;
1239- const ELEMENT_BIT_WIDTH : usize = <$elem_type >:: BIT_WIDTH ;
1226+ macro_rules! impl_bitblock {
1227+ ( $type: ty, $item_type : ty, $lanes: expr) => {
1228+ impl BitBlock <$lanes> for $type {
1229+ type Item = $item_type ;
1230+ const BIT_WIDTH : usize = ( $lanes * <$item_type >:: BIT_WIDTH ) as usize ;
1231+ const ELEMENT_BIT_WIDTH : usize = <$item_type >:: BIT_WIDTH ;
12401232 const LANES : usize = $lanes;
1241- const ZERO_ELEMENT : $elem_type = <$elem_type >:: ZERO ;
1242- const ONE_ELEMENT : $elem_type = <$elem_type >:: ONE ;
1243- const MAX_ELEMENT : $elem_type = <$elem_type >:: MAX ;
1233+ const ZERO_ELEMENT : $item_type = <$item_type >:: ZERO ;
1234+ const ONE_ELEMENT : $item_type = <$item_type >:: ONE ;
1235+ const MAX_ELEMENT : $item_type = <$item_type >:: MAX ;
12441236 const ZERO : Self = <$type>:: splat( 0 ) ;
1245- const MAX : Self = <$type>:: splat( <$elem_type >:: MAX ) ;
1237+ const MAX : Self = <$type>:: splat( <$item_type >:: MAX ) ;
12461238
12471239 #[ inline]
1248- fn to_array( self ) -> [ $elem_type ; $lanes] {
1240+ fn to_array( self ) -> [ $item_type ; $lanes] {
12491241 <$type>:: to_array( self )
12501242 }
12511243
@@ -1267,9 +1259,10 @@ macro_rules! impl_bitcontainer {
12671259 } ;
12681260}
12691261
1270- impl_bitcontainer ! ( u8x16, u8 , 16 ) ;
1271- impl_bitcontainer ! ( u16x8, u16 , 8 ) ;
1272- impl_bitcontainer ! ( u32x4, u32 , 4 ) ;
1273- impl_bitcontainer ! ( u32x8, u32 , 8 ) ;
1274- impl_bitcontainer ! ( u64x2, u64 , 2 ) ;
1275- impl_bitcontainer ! ( u64x4, u64 , 4 ) ;
1262+ impl_bitblock ! ( u8x16, u8 , 16 ) ;
1263+ impl_bitblock ! ( u16x8, u16 , 8 ) ;
1264+ impl_bitblock ! ( u32x4, u32 , 4 ) ;
1265+ impl_bitblock ! ( u32x8, u32 , 8 ) ;
1266+ impl_bitblock ! ( u64x2, u64 , 2 ) ;
1267+ impl_bitblock ! ( u64x4, u64 , 4 ) ;
1268+ impl_bitblock ! ( u64x8, u64 , 8 ) ;
0 commit comments