@@ -6,30 +6,64 @@ use test::{black_box, Bencher};
66extern crate compiler_builtins;
77use compiler_builtins:: mem:: { memcmp, memcpy, memmove, memset} ;
88
9- fn memcpy_builtin ( b : & mut Bencher , n : usize , offset : usize ) {
10- let v1 = vec ! [ 1u8 ; n + offset] ;
11- let mut v2 = vec ! [ 0u8 ; n + offset] ;
9+ const WORD_SIZE : usize = core:: mem:: size_of :: < usize > ( ) ;
10+
11+ struct AlignedVec {
12+ vec : Vec < usize > ,
13+ size : usize ,
14+ }
15+
16+ impl AlignedVec {
17+ fn new ( fill : u8 , size : usize ) -> Self {
18+ let mut broadcast = fill as usize ;
19+ let mut bits = 8 ;
20+ while bits < WORD_SIZE * 8 {
21+ broadcast |= broadcast << bits;
22+ bits *= 2 ;
23+ }
24+
25+ let vec = vec ! [ broadcast; ( size + WORD_SIZE - 1 ) & !WORD_SIZE ] ;
26+ AlignedVec { vec, size }
27+ }
28+ }
29+
30+ impl core:: ops:: Deref for AlignedVec {
31+ type Target = [ u8 ] ;
32+ fn deref ( & self ) -> & [ u8 ] {
33+ unsafe { core:: slice:: from_raw_parts ( self . vec . as_ptr ( ) as * const u8 , self . size ) }
34+ }
35+ }
36+
37+ impl core:: ops:: DerefMut for AlignedVec {
38+ fn deref_mut ( & mut self ) -> & mut [ u8 ] {
39+ unsafe { core:: slice:: from_raw_parts_mut ( self . vec . as_mut_ptr ( ) as * mut u8 , self . size ) }
40+ }
41+ }
42+
43+ fn memcpy_builtin ( b : & mut Bencher , n : usize , offset1 : usize , offset2 : usize ) {
44+ let v1 = AlignedVec :: new ( 1 , n + offset1) ;
45+ let mut v2 = AlignedVec :: new ( 0 , n + offset2) ;
1246 b. bytes = n as u64 ;
1347 b. iter ( || {
14- let src: & [ u8 ] = black_box ( & v1[ offset ..] ) ;
15- let dst: & mut [ u8 ] = black_box ( & mut v2[ offset ..] ) ;
48+ let src: & [ u8 ] = black_box ( & v1[ offset1 ..] ) ;
49+ let dst: & mut [ u8 ] = black_box ( & mut v2[ offset2 ..] ) ;
1650 dst. copy_from_slice ( src) ;
1751 } )
1852}
1953
20- fn memcpy_rust ( b : & mut Bencher , n : usize , offset : usize ) {
21- let v1 = vec ! [ 1u8 ; n + offset ] ;
22- let mut v2 = vec ! [ 0u8 ; n + offset ] ;
54+ fn memcpy_rust ( b : & mut Bencher , n : usize , offset1 : usize , offset2 : usize ) {
55+ let v1 = AlignedVec :: new ( 1 , n + offset1 ) ;
56+ let mut v2 = AlignedVec :: new ( 0 , n + offset2 ) ;
2357 b. bytes = n as u64 ;
2458 b. iter ( || {
25- let src: & [ u8 ] = black_box ( & v1[ offset ..] ) ;
26- let dst: & mut [ u8 ] = black_box ( & mut v2[ offset ..] ) ;
59+ let src: & [ u8 ] = black_box ( & v1[ offset1 ..] ) ;
60+ let dst: & mut [ u8 ] = black_box ( & mut v2[ offset2 ..] ) ;
2761 unsafe { memcpy ( dst. as_mut_ptr ( ) , src. as_ptr ( ) , n) }
2862 } )
2963}
3064
3165fn memset_builtin ( b : & mut Bencher , n : usize , offset : usize ) {
32- let mut v1 = vec ! [ 0u8 ; n + offset] ;
66+ let mut v1 = AlignedVec :: new ( 0 , n + offset) ;
3367 b. bytes = n as u64 ;
3468 b. iter ( || {
3569 let dst: & mut [ u8 ] = black_box ( & mut v1[ offset..] ) ;
@@ -41,7 +75,7 @@ fn memset_builtin(b: &mut Bencher, n: usize, offset: usize) {
4175}
4276
4377fn memset_rust ( b : & mut Bencher , n : usize , offset : usize ) {
44- let mut v1 = vec ! [ 0u8 ; n + offset] ;
78+ let mut v1 = AlignedVec :: new ( 0 , n + offset) ;
4579 b. bytes = n as u64 ;
4680 b. iter ( || {
4781 let dst: & mut [ u8 ] = black_box ( & mut v1[ offset..] ) ;
@@ -51,8 +85,8 @@ fn memset_rust(b: &mut Bencher, n: usize, offset: usize) {
5185}
5286
5387fn memcmp_builtin ( b : & mut Bencher , n : usize ) {
54- let v1 = vec ! [ 0u8 ; n ] ;
55- let mut v2 = vec ! [ 0u8 ; n ] ;
88+ let v1 = AlignedVec :: new ( 0 , n ) ;
89+ let mut v2 = AlignedVec :: new ( 0 , n ) ;
5690 v2[ n - 1 ] = 1 ;
5791 b. bytes = n as u64 ;
5892 b. iter ( || {
@@ -63,8 +97,8 @@ fn memcmp_builtin(b: &mut Bencher, n: usize) {
6397}
6498
6599fn memcmp_rust ( b : & mut Bencher , n : usize ) {
66- let v1 = vec ! [ 0u8 ; n ] ;
67- let mut v2 = vec ! [ 0u8 ; n ] ;
100+ let v1 = AlignedVec :: new ( 0 , n ) ;
101+ let mut v2 = AlignedVec :: new ( 0 , n ) ;
68102 v2[ n - 1 ] = 1 ;
69103 b. bytes = n as u64 ;
70104 b. iter ( || {
@@ -74,56 +108,72 @@ fn memcmp_rust(b: &mut Bencher, n: usize) {
74108 } )
75109}
76110
77- fn memmove_builtin ( b : & mut Bencher , n : usize ) {
78- let mut v = vec ! [ 0u8 ; n + n / 2 ] ;
111+ fn memmove_builtin ( b : & mut Bencher , n : usize , offset : usize ) {
112+ let mut v = AlignedVec :: new ( 0 , n + n / 2 + offset ) ;
79113 b. bytes = n as u64 ;
80114 b. iter ( || {
81115 let s: & mut [ u8 ] = black_box ( & mut v) ;
82- s. copy_within ( 0 ..n, n / 2 ) ;
116+ s. copy_within ( 0 ..n, n / 2 + offset ) ;
83117 } )
84118}
85119
86- fn memmove_rust ( b : & mut Bencher , n : usize ) {
87- let mut v = vec ! [ 0u8 ; n + n / 2 ] ;
120+ fn memmove_rust ( b : & mut Bencher , n : usize , offset : usize ) {
121+ let mut v = AlignedVec :: new ( 0 , n + n / 2 + offset ) ;
88122 b. bytes = n as u64 ;
89123 b. iter ( || {
90- let dst: * mut u8 = black_box ( & mut v[ n / 2 ..] ) . as_mut_ptr ( ) ;
124+ let dst: * mut u8 = black_box ( & mut v[ n / 2 + offset ..] ) . as_mut_ptr ( ) ;
91125 let src: * const u8 = black_box ( & v) . as_ptr ( ) ;
92126 unsafe { memmove ( dst, src, n) } ;
93127 } )
94128}
95129
96130#[ bench]
97131fn memcpy_builtin_4096 ( b : & mut Bencher ) {
98- memcpy_builtin ( b, 4096 , 0 )
132+ memcpy_builtin ( b, 4096 , 0 , 0 )
99133}
100134#[ bench]
101135fn memcpy_rust_4096 ( b : & mut Bencher ) {
102- memcpy_rust ( b, 4096 , 0 )
136+ memcpy_rust ( b, 4096 , 0 , 0 )
103137}
104138#[ bench]
105139fn memcpy_builtin_1048576 ( b : & mut Bencher ) {
106- memcpy_builtin ( b, 1048576 , 0 )
140+ memcpy_builtin ( b, 1048576 , 0 , 0 )
107141}
108142#[ bench]
109143fn memcpy_rust_1048576 ( b : & mut Bencher ) {
110- memcpy_rust ( b, 1048576 , 0 )
144+ memcpy_rust ( b, 1048576 , 0 , 0 )
111145}
112146#[ bench]
113147fn memcpy_builtin_4096_offset ( b : & mut Bencher ) {
114- memcpy_builtin ( b, 4096 , 65 )
148+ memcpy_builtin ( b, 4096 , 65 , 65 )
115149}
116150#[ bench]
117151fn memcpy_rust_4096_offset ( b : & mut Bencher ) {
118- memcpy_rust ( b, 4096 , 65 )
152+ memcpy_rust ( b, 4096 , 65 , 65 )
119153}
120154#[ bench]
121155fn memcpy_builtin_1048576_offset ( b : & mut Bencher ) {
122- memcpy_builtin ( b, 1048576 , 65 )
156+ memcpy_builtin ( b, 1048576 , 65 , 65 )
123157}
124158#[ bench]
125159fn memcpy_rust_1048576_offset ( b : & mut Bencher ) {
126- memcpy_rust ( b, 1048576 , 65 )
160+ memcpy_rust ( b, 1048576 , 65 , 65 )
161+ }
162+ #[ bench]
163+ fn memcpy_builtin_4096_misalign ( b : & mut Bencher ) {
164+ memcpy_builtin ( b, 4096 , 65 , 66 )
165+ }
166+ #[ bench]
167+ fn memcpy_rust_4096_misalign ( b : & mut Bencher ) {
168+ memcpy_rust ( b, 4096 , 65 , 66 )
169+ }
170+ #[ bench]
171+ fn memcpy_builtin_1048576_misalign ( b : & mut Bencher ) {
172+ memcpy_builtin ( b, 1048576 , 65 , 66 )
173+ }
174+ #[ bench]
175+ fn memcpy_rust_1048576_misalign ( b : & mut Bencher ) {
176+ memcpy_rust ( b, 1048576 , 65 , 66 )
127177}
128178
129179#[ bench]
@@ -178,17 +228,33 @@ fn memcmp_rust_1048576(b: &mut Bencher) {
178228
179229#[ bench]
180230fn memmove_builtin_4096 ( b : & mut Bencher ) {
181- memmove_builtin ( b, 4096 )
231+ memmove_builtin ( b, 4096 , 0 )
182232}
183233#[ bench]
184234fn memmove_rust_4096 ( b : & mut Bencher ) {
185- memmove_rust ( b, 4096 )
235+ memmove_rust ( b, 4096 , 0 )
186236}
187237#[ bench]
188238fn memmove_builtin_1048576 ( b : & mut Bencher ) {
189- memmove_builtin ( b, 1048576 )
239+ memmove_builtin ( b, 1048576 , 0 )
190240}
191241#[ bench]
192242fn memmove_rust_1048576 ( b : & mut Bencher ) {
193- memmove_rust ( b, 1048576 )
243+ memmove_rust ( b, 1048576 , 0 )
244+ }
245+ #[ bench]
246+ fn memmove_builtin_4096_misalign ( b : & mut Bencher ) {
247+ memmove_builtin ( b, 4096 , 1 )
248+ }
249+ #[ bench]
250+ fn memmove_rust_4096_misalign ( b : & mut Bencher ) {
251+ memmove_rust ( b, 4096 , 1 )
252+ }
253+ #[ bench]
254+ fn memmove_builtin_1048576_misalign ( b : & mut Bencher ) {
255+ memmove_builtin ( b, 1048576 , 1 )
256+ }
257+ #[ bench]
258+ fn memmove_rust_1048576_misalign ( b : & mut Bencher ) {
259+ memmove_rust ( b, 1048576 , 1 )
194260}
0 commit comments