@@ -6,30 +6,64 @@ use test::{black_box, Bencher};
6
6
extern crate compiler_builtins;
7
7
use compiler_builtins:: mem:: { memcmp, memcpy, memmove, memset} ;
8
8
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) ;
12
46
b. bytes = n as u64 ;
13
47
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 ..] ) ;
16
50
dst. copy_from_slice ( src) ;
17
51
} )
18
52
}
19
53
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 ) ;
23
57
b. bytes = n as u64 ;
24
58
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 ..] ) ;
27
61
unsafe { memcpy ( dst. as_mut_ptr ( ) , src. as_ptr ( ) , n) }
28
62
} )
29
63
}
30
64
31
65
fn 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) ;
33
67
b. bytes = n as u64 ;
34
68
b. iter ( || {
35
69
let dst: & mut [ u8 ] = black_box ( & mut v1[ offset..] ) ;
@@ -41,7 +75,7 @@ fn memset_builtin(b: &mut Bencher, n: usize, offset: usize) {
41
75
}
42
76
43
77
fn 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) ;
45
79
b. bytes = n as u64 ;
46
80
b. iter ( || {
47
81
let dst: & mut [ u8 ] = black_box ( & mut v1[ offset..] ) ;
@@ -51,8 +85,8 @@ fn memset_rust(b: &mut Bencher, n: usize, offset: usize) {
51
85
}
52
86
53
87
fn 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 ) ;
56
90
v2[ n - 1 ] = 1 ;
57
91
b. bytes = n as u64 ;
58
92
b. iter ( || {
@@ -63,8 +97,8 @@ fn memcmp_builtin(b: &mut Bencher, n: usize) {
63
97
}
64
98
65
99
fn 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 ) ;
68
102
v2[ n - 1 ] = 1 ;
69
103
b. bytes = n as u64 ;
70
104
b. iter ( || {
@@ -74,56 +108,72 @@ fn memcmp_rust(b: &mut Bencher, n: usize) {
74
108
} )
75
109
}
76
110
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 ) ;
79
113
b. bytes = n as u64 ;
80
114
b. iter ( || {
81
115
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 ) ;
83
117
} )
84
118
}
85
119
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 ) ;
88
122
b. bytes = n as u64 ;
89
123
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 ( ) ;
91
125
let src: * const u8 = black_box ( & v) . as_ptr ( ) ;
92
126
unsafe { memmove ( dst, src, n) } ;
93
127
} )
94
128
}
95
129
96
130
#[ bench]
97
131
fn memcpy_builtin_4096 ( b : & mut Bencher ) {
98
- memcpy_builtin ( b, 4096 , 0 )
132
+ memcpy_builtin ( b, 4096 , 0 , 0 )
99
133
}
100
134
#[ bench]
101
135
fn memcpy_rust_4096 ( b : & mut Bencher ) {
102
- memcpy_rust ( b, 4096 , 0 )
136
+ memcpy_rust ( b, 4096 , 0 , 0 )
103
137
}
104
138
#[ bench]
105
139
fn memcpy_builtin_1048576 ( b : & mut Bencher ) {
106
- memcpy_builtin ( b, 1048576 , 0 )
140
+ memcpy_builtin ( b, 1048576 , 0 , 0 )
107
141
}
108
142
#[ bench]
109
143
fn memcpy_rust_1048576 ( b : & mut Bencher ) {
110
- memcpy_rust ( b, 1048576 , 0 )
144
+ memcpy_rust ( b, 1048576 , 0 , 0 )
111
145
}
112
146
#[ bench]
113
147
fn memcpy_builtin_4096_offset ( b : & mut Bencher ) {
114
- memcpy_builtin ( b, 4096 , 65 )
148
+ memcpy_builtin ( b, 4096 , 65 , 65 )
115
149
}
116
150
#[ bench]
117
151
fn memcpy_rust_4096_offset ( b : & mut Bencher ) {
118
- memcpy_rust ( b, 4096 , 65 )
152
+ memcpy_rust ( b, 4096 , 65 , 65 )
119
153
}
120
154
#[ bench]
121
155
fn memcpy_builtin_1048576_offset ( b : & mut Bencher ) {
122
- memcpy_builtin ( b, 1048576 , 65 )
156
+ memcpy_builtin ( b, 1048576 , 65 , 65 )
123
157
}
124
158
#[ bench]
125
159
fn 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 )
127
177
}
128
178
129
179
#[ bench]
@@ -178,17 +228,33 @@ fn memcmp_rust_1048576(b: &mut Bencher) {
178
228
179
229
#[ bench]
180
230
fn memmove_builtin_4096 ( b : & mut Bencher ) {
181
- memmove_builtin ( b, 4096 )
231
+ memmove_builtin ( b, 4096 , 0 )
182
232
}
183
233
#[ bench]
184
234
fn memmove_rust_4096 ( b : & mut Bencher ) {
185
- memmove_rust ( b, 4096 )
235
+ memmove_rust ( b, 4096 , 0 )
186
236
}
187
237
#[ bench]
188
238
fn memmove_builtin_1048576 ( b : & mut Bencher ) {
189
- memmove_builtin ( b, 1048576 )
239
+ memmove_builtin ( b, 1048576 , 0 )
190
240
}
191
241
#[ bench]
192
242
fn 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 )
194
260
}
0 commit comments