blob: 9be54c7b539b03b226492163f8640902a8b3a34f [file] [log] [blame]
Elliott Hughes7be369d2012-11-08 15:37:43 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Anders Lewisa98a5fb2017-08-09 16:52:19 -070017#include <err.h>
Christopher Ferrisdf4942c2015-02-17 19:58:53 -080018#include <stdint.h>
Elliott Hughes7be369d2012-11-08 15:37:43 -080019#include <string.h>
20
Elliott Hughes281e06b2016-02-17 10:23:52 -080021#include <benchmark/benchmark.h>
Anders Lewisa7b0f882017-07-24 20:01:13 -070022#include <util.h>
Elliott Hughes7be369d2012-11-08 15:37:43 -080023
Elliott Hughes281e06b2016-02-17 10:23:52 -080024static void BM_string_memcmp(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010025 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070026 const size_t src_alignment = state.range(1);
27 const size_t dst_alignment = state.range(2);
28
29 std::vector<char> src;
30 std::vector<char> dst;
31 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
32 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'x');
Elliott Hughes7be369d2012-11-08 15:37:43 -080033
Elliott Hughes281e06b2016-02-17 10:23:52 -080034 while (state.KeepRunning()) {
Elliott Hughese8693e72020-10-22 13:43:59 -070035 benchmark::DoNotOptimize(memcmp(dst_aligned, src_aligned, nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -080036 }
37
Elliott Hughes281e06b2016-02-17 10:23:52 -080038 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -080039}
Christopher Ferris858e3362017-11-30 08:53:15 -080040BIONIC_BENCHMARK_WITH_ARG(BM_string_memcmp, "AT_ALIGNED_TWOBUF");
Elliott Hughes7be369d2012-11-08 15:37:43 -080041
Elliott Hughes281e06b2016-02-17 10:23:52 -080042static void BM_string_memcpy(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010043 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070044 const size_t src_alignment = state.range(1);
45 const size_t dst_alignment = state.range(2);
46
47 std::vector<char> src;
48 std::vector<char> dst;
49 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
50 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -080051
Elliott Hughes281e06b2016-02-17 10:23:52 -080052 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070053 memcpy(dst_aligned, src_aligned, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -080054 }
55
Elliott Hughes281e06b2016-02-17 10:23:52 -080056 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -080057}
Christopher Ferris858e3362017-11-30 08:53:15 -080058BIONIC_BENCHMARK_WITH_ARG(BM_string_memcpy, "AT_ALIGNED_TWOBUF");
Elliott Hughes7be369d2012-11-08 15:37:43 -080059
Anders Lewis271be9b2017-06-07 13:00:38 -070060static void BM_string_memmove_non_overlapping(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010061 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070062 const size_t src_alignment = state.range(1);
63 const size_t dst_alignment = state.range(2);
64
65 std::vector<char> src;
66 std::vector<char> dst;
67 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
68 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080069
Elliott Hughes281e06b2016-02-17 10:23:52 -080070 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070071 memmove(dst_aligned, src_aligned, nbytes);
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080072 }
73
Elliott Hughes281e06b2016-02-17 10:23:52 -080074 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080075}
Christopher Ferris858e3362017-11-30 08:53:15 -080076BIONIC_BENCHMARK_WITH_ARG(BM_string_memmove_non_overlapping, "AT_ALIGNED_TWOBUF");
Anders Lewis271be9b2017-06-07 13:00:38 -070077
78static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) {
79 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070080 const size_t alignment = state.range(1);
81
82 std::vector<char> buf(3 * alignment + nbytes + 1, 'x');
83 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
Anders Lewis271be9b2017-06-07 13:00:38 -070084
85 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070086 memmove(buf_aligned, buf_aligned + 1, nbytes); // Worst-case overlap.
Anders Lewis271be9b2017-06-07 13:00:38 -070087 }
88
89 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
90}
Christopher Ferris858e3362017-11-30 08:53:15 -080091BIONIC_BENCHMARK_WITH_ARG(BM_string_memmove_overlap_dst_before_src, "AT_ALIGNED_ONEBUF");
Anders Lewis271be9b2017-06-07 13:00:38 -070092
93static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
94 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070095 const size_t alignment = state.range(1);
96
97 std::vector<char> buf;
98 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
Anders Lewis271be9b2017-06-07 13:00:38 -070099
100 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700101 memmove(buf_aligned + 1, buf_aligned, nbytes); // Worst-case overlap.
Anders Lewis271be9b2017-06-07 13:00:38 -0700102 }
103
104 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
105}
Christopher Ferris858e3362017-11-30 08:53:15 -0800106BIONIC_BENCHMARK_WITH_ARG(BM_string_memmove_overlap_src_before_dst, "AT_ALIGNED_ONEBUF");
Elliott Hughesfbe44ec2012-11-09 14:59:21 -0800107
Elliott Hughes281e06b2016-02-17 10:23:52 -0800108static void BM_string_memset(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +0100109 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700110 const size_t alignment = state.range(1);
111
112 std::vector<char> buf;
113 char* buf_aligned = GetAlignedPtr(&buf, alignment, nbytes + 1);
Elliott Hughes7be369d2012-11-08 15:37:43 -0800114
Elliott Hughes281e06b2016-02-17 10:23:52 -0800115 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700116 memset(buf_aligned, 0, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -0800117 }
118
Elliott Hughes281e06b2016-02-17 10:23:52 -0800119 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -0800120}
Christopher Ferris858e3362017-11-30 08:53:15 -0800121BIONIC_BENCHMARK_WITH_ARG(BM_string_memset, "AT_ALIGNED_ONEBUF");
Elliott Hughes7be369d2012-11-08 15:37:43 -0800122
Elliott Hughes281e06b2016-02-17 10:23:52 -0800123static void BM_string_strlen(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +0100124 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700125 const size_t alignment = state.range(1);
126
127 std::vector<char> buf;
128 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
129 buf_aligned[nbytes - 1] = '\0';
Elliott Hughes7be369d2012-11-08 15:37:43 -0800130
Elliott Hughes281e06b2016-02-17 10:23:52 -0800131 while (state.KeepRunning()) {
Elliott Hughese8693e72020-10-22 13:43:59 -0700132 benchmark::DoNotOptimize(strlen(buf_aligned));
Elliott Hughes7be369d2012-11-08 15:37:43 -0800133 }
134
Elliott Hughes281e06b2016-02-17 10:23:52 -0800135 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -0800136}
Christopher Ferris858e3362017-11-30 08:53:15 -0800137BIONIC_BENCHMARK_WITH_ARG(BM_string_strlen, "AT_ALIGNED_ONEBUF");
Anders Lewisa99d0522017-06-12 11:24:01 -0700138
139static void BM_string_strcat_copy_only(benchmark::State& state) {
140 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700141 const size_t src_alignment = state.range(1);
142 const size_t dst_alignment = state.range(2);
143
144 std::vector<char> src;
145 std::vector<char> dst;
146 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
147 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes + 2);
148 src_aligned[nbytes - 1] = '\0';
149 dst_aligned[0] = 'y';
150 dst_aligned[1] = 'y';
151 dst_aligned[2] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700152
153 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700154 strcat(dst_aligned, src_aligned);
155 dst_aligned[2] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700156 }
157
158 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
159}
Christopher Ferris858e3362017-11-30 08:53:15 -0800160BIONIC_BENCHMARK_WITH_ARG(BM_string_strcat_copy_only, "AT_ALIGNED_TWOBUF");
Anders Lewisa99d0522017-06-12 11:24:01 -0700161
162static void BM_string_strcat_seek_only(benchmark::State& state) {
163 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700164 const size_t src_alignment = state.range(1);
165 const size_t dst_alignment = state.range(2);
166
167 std::vector<char> src;
168 std::vector<char> dst;
169 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, 3, 'x');
170 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes + 2, 'y');
171 src_aligned[2] = '\0';
172 dst_aligned[nbytes - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700173
174 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700175 strcat(dst_aligned, src_aligned);
176 dst_aligned[nbytes - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700177 }
178
179 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
180}
Christopher Ferris858e3362017-11-30 08:53:15 -0800181BIONIC_BENCHMARK_WITH_ARG(BM_string_strcat_seek_only, "AT_ALIGNED_TWOBUF");
Anders Lewisa99d0522017-06-12 11:24:01 -0700182
183static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) {
184 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700185 const size_t src_alignment = state.range(1);
186 const size_t dst_alignment = state.range(2);
187
Christopher Ferrise2188d42017-11-08 23:28:57 -0800188 // Skip sizes that don't make sense.
189 if ((nbytes / 2) == 0) {
190 return;
191 }
192
Anders Lewisf4447b92017-06-23 15:53:59 -0700193 std::vector<char> src;
194 std::vector<char> dst;
195 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes / 2, 'x');
196 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
197 src_aligned[nbytes / 2 - 1] = '\0';
198 dst_aligned[nbytes / 2 - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700199
200 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700201 strcat(dst_aligned, src_aligned);
202 dst_aligned[nbytes / 2 - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700203 }
204
205 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
206}
Christopher Ferris858e3362017-11-30 08:53:15 -0800207BIONIC_BENCHMARK_WITH_ARG(BM_string_strcat_half_copy_half_seek, "AT_ALIGNED_TWOBUF");
Anders Lewis1c487e12017-06-12 12:33:06 -0700208
209static void BM_string_strcpy(benchmark::State& state) {
210 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700211 const size_t src_alignment = state.range(1);
212 const size_t dst_alignment = state.range(2);
213
214 std::vector<char> src;
215 std::vector<char> dst;
216 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
217 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
218 src_aligned[nbytes - 1] = '\0';
Anders Lewis1c487e12017-06-12 12:33:06 -0700219
220 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700221 strcpy(dst_aligned, src_aligned);
Anders Lewis1c487e12017-06-12 12:33:06 -0700222 }
223
224 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
225}
Christopher Ferris858e3362017-11-30 08:53:15 -0800226BIONIC_BENCHMARK_WITH_ARG(BM_string_strcpy, "AT_ALIGNED_TWOBUF");
Anders Lewis1c487e12017-06-12 12:33:06 -0700227
228static void BM_string_strcmp(benchmark::State& state) {
229 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700230 const size_t s1_alignment = state.range(1);
231 const size_t s2_alignment = state.range(2);
232
233 std::vector<char> s1;
234 std::vector<char> s2;
235 char* s1_aligned = GetAlignedPtrFilled(&s1, s1_alignment, nbytes, 'x');
236 char* s2_aligned = GetAlignedPtrFilled(&s2, s2_alignment, nbytes, 'x');
237 s1_aligned[nbytes - 1] = '\0';
238 s2_aligned[nbytes - 1] = '\0';
Anders Lewis1c487e12017-06-12 12:33:06 -0700239
Anders Lewis1c487e12017-06-12 12:33:06 -0700240 while (state.KeepRunning()) {
Elliott Hughese8693e72020-10-22 13:43:59 -0700241 benchmark::DoNotOptimize(strcmp(s1_aligned, s2_aligned));
Anders Lewis1c487e12017-06-12 12:33:06 -0700242 }
243
244 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
245}
Christopher Ferris858e3362017-11-30 08:53:15 -0800246BIONIC_BENCHMARK_WITH_ARG(BM_string_strcmp, "AT_ALIGNED_TWOBUF");
Anders Lewisac4f4b42017-08-08 18:29:51 -0700247
Haibo Huange466cc02018-08-21 12:55:37 -0700248static void BM_string_strncmp(benchmark::State& state) {
249 const size_t nbytes = state.range(0);
250 const size_t s1_alignment = state.range(1);
251 const size_t s2_alignment = state.range(2);
252
253 std::vector<char> s1;
254 std::vector<char> s2;
255 char* s1_aligned = GetAlignedPtrFilled(&s1, s1_alignment, nbytes, 'x');
256 char* s2_aligned = GetAlignedPtrFilled(&s2, s2_alignment, nbytes, 'x');
257
Haibo Huange466cc02018-08-21 12:55:37 -0700258 for (auto _ : state) {
Elliott Hughese8693e72020-10-22 13:43:59 -0700259 benchmark::DoNotOptimize(strncmp(s1_aligned, s2_aligned, nbytes));
Haibo Huange466cc02018-08-21 12:55:37 -0700260 }
261
262 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
263}
264BIONIC_BENCHMARK_WITH_ARG(BM_string_strncmp, "AT_ALIGNED_TWOBUF");
265
Anders Lewisac4f4b42017-08-08 18:29:51 -0700266static void BM_string_strstr(benchmark::State& state) {
267 const size_t nbytes = state.range(0);
268 const size_t haystack_alignment = state.range(1);
269 const size_t needle_alignment = state.range(2);
270
271 std::vector<char> haystack;
272 std::vector<char> needle;
273 char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
274 char* needle_aligned = GetAlignedPtrFilled(&needle, needle_alignment,
275 std::min(nbytes, static_cast<size_t>(5)), 'x');
276
277 if (nbytes / 4 > 2) {
278 for (size_t i = 0; nbytes / 4 >= 2 && i < nbytes / 4 - 2; i++) {
279 haystack_aligned[4 * i + 3] = 'y';
280 }
281 }
282 haystack_aligned[nbytes - 1] = '\0';
283 needle_aligned[needle.size() - 1] = '\0';
284
285 while (state.KeepRunning()) {
286 if (strstr(haystack_aligned, needle_aligned) == nullptr) {
Anders Lewisa98a5fb2017-08-09 16:52:19 -0700287 errx(1, "ERROR: strstr failed to find valid substring.");
Anders Lewisac4f4b42017-08-08 18:29:51 -0700288 }
289 }
290
291 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
292}
Christopher Ferris858e3362017-11-30 08:53:15 -0800293BIONIC_BENCHMARK_WITH_ARG(BM_string_strstr, "AT_ALIGNED_TWOBUF");
Anders Lewisac4f4b42017-08-08 18:29:51 -0700294
295static void BM_string_strchr(benchmark::State& state) {
296 const size_t nbytes = state.range(0);
297 const size_t haystack_alignment = state.range(1);
298
299 std::vector<char> haystack;
300 char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
Anders Lewisa98a5fb2017-08-09 16:52:19 -0700301 haystack_aligned[nbytes-1] = '\0';
Anders Lewisac4f4b42017-08-08 18:29:51 -0700302
303 while (state.KeepRunning()) {
304 if (strchr(haystack_aligned, 'y') != nullptr) {
Anders Lewisa98a5fb2017-08-09 16:52:19 -0700305 errx(1, "ERROR: strchr found a chr where it should have failed.");
Anders Lewisac4f4b42017-08-08 18:29:51 -0700306 }
307 }
308
309 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
310}
Christopher Ferris858e3362017-11-30 08:53:15 -0800311BIONIC_BENCHMARK_WITH_ARG(BM_string_strchr, "AT_ALIGNED_ONEBUF");