blob: 2ab65a891689115a400a50c3e461ac036b7f8c90 [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
Christopher Ferrisdf4942c2015-02-17 19:58:53 -080017#include <stdint.h>
Elliott Hughes7be369d2012-11-08 15:37:43 -080018#include <string.h>
19
Elliott Hughes281e06b2016-02-17 10:23:52 -080020#include <benchmark/benchmark.h>
Anders Lewisf4447b92017-06-23 15:53:59 -070021#include "util.h"
Christopher Ferrisdf4942c2015-02-17 19:58:53 -080022
Chih-Hung Hsieh1a5fd9c2016-06-10 11:07:21 -070023constexpr auto KB = 1024;
Elliott Hughes7be369d2012-11-08 15:37:43 -080024
Anders Lewisf4447b92017-06-23 15:53:59 -070025// NOTE: these constants are temporary replacements for AT_COMMON_SIZES until
26// the new interface for Bionic benchmarks is implemented.
Elliott Hughes7be369d2012-11-08 15:37:43 -080027
Anders Lewisf4447b92017-06-23 15:53:59 -070028// Set all four to 0 to test normal alignment.
29#define AT_SRC_ALIGN 0
30#define AT_DST_ALIGN 0
31
32#define AT_ALIGNED_TWOBUF \
33 Args({(8), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
34 Args({(512), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(1*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
35 Args({(8*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(16*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
36 Args({(32*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64*KB), AT_SRC_ALIGN, AT_DST_ALIGN})
37
38#define AT_ALIGNED_ONEBUF \
39 Args({(8), AT_SRC_ALIGN})->Args({(64), AT_SRC_ALIGN})->Args({(512), AT_SRC_ALIGN})-> \
40 Args({(1*KB), AT_SRC_ALIGN})->Args({(8*KB), AT_SRC_ALIGN})->Args({(16*KB), AT_SRC_ALIGN})-> \
41 Args({(32*KB), AT_SRC_ALIGN})->Args({(64*KB), AT_SRC_ALIGN})
Elliott Hughes7be369d2012-11-08 15:37:43 -080042
Elliott Hughes281e06b2016-02-17 10:23:52 -080043static void BM_string_memcmp(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010044 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070045 const size_t src_alignment = state.range(1);
46 const size_t dst_alignment = state.range(2);
47
48 std::vector<char> src;
49 std::vector<char> dst;
50 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
51 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'x');
Elliott Hughes7be369d2012-11-08 15:37:43 -080052
53 volatile int c __attribute__((unused)) = 0;
Elliott Hughes281e06b2016-02-17 10:23:52 -080054 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070055 c += memcmp(dst_aligned, src_aligned, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -080056 }
57
Elliott Hughes281e06b2016-02-17 10:23:52 -080058 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -080059}
Anders Lewisf4447b92017-06-23 15:53:59 -070060BENCHMARK(BM_string_memcmp)->AT_ALIGNED_TWOBUF;
Elliott Hughes7be369d2012-11-08 15:37:43 -080061
Elliott Hughes281e06b2016-02-17 10:23:52 -080062static void BM_string_memcpy(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010063 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070064 const size_t src_alignment = state.range(1);
65 const size_t dst_alignment = state.range(2);
66
67 std::vector<char> src;
68 std::vector<char> dst;
69 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
70 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -080071
Elliott Hughes281e06b2016-02-17 10:23:52 -080072 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070073 memcpy(dst_aligned, src_aligned, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -080074 }
75
Elliott Hughes281e06b2016-02-17 10:23:52 -080076 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -080077}
Anders Lewisf4447b92017-06-23 15:53:59 -070078BENCHMARK(BM_string_memcpy)->AT_ALIGNED_TWOBUF;
Elliott Hughes7be369d2012-11-08 15:37:43 -080079
Anders Lewis271be9b2017-06-07 13:00:38 -070080static void BM_string_memmove_non_overlapping(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +010081 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -070082 const size_t src_alignment = state.range(1);
83 const size_t dst_alignment = state.range(2);
84
85 std::vector<char> src;
86 std::vector<char> dst;
87 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
88 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080089
Elliott Hughes281e06b2016-02-17 10:23:52 -080090 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -070091 memmove(dst_aligned, src_aligned, nbytes);
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080092 }
93
Elliott Hughes281e06b2016-02-17 10:23:52 -080094 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughesfbe44ec2012-11-09 14:59:21 -080095}
Anders Lewisf4447b92017-06-23 15:53:59 -070096BENCHMARK(BM_string_memmove_non_overlapping)->AT_ALIGNED_TWOBUF;
Anders Lewis271be9b2017-06-07 13:00:38 -070097
98static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) {
99 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700100 const size_t alignment = state.range(1);
101
102 std::vector<char> buf(3 * alignment + nbytes + 1, 'x');
103 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
Anders Lewis271be9b2017-06-07 13:00:38 -0700104
105 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700106 memmove(buf_aligned, buf_aligned + 1, nbytes); // Worst-case overlap.
Anders Lewis271be9b2017-06-07 13:00:38 -0700107 }
108
109 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
110}
Anders Lewisf4447b92017-06-23 15:53:59 -0700111BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_ALIGNED_ONEBUF;
Anders Lewis271be9b2017-06-07 13:00:38 -0700112
113static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
114 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700115 const size_t alignment = state.range(1);
116
117 std::vector<char> buf;
118 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
Anders Lewis271be9b2017-06-07 13:00:38 -0700119
120 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700121 memmove(buf_aligned + 1, buf_aligned, nbytes); // Worst-case overlap.
Anders Lewis271be9b2017-06-07 13:00:38 -0700122 }
123
124 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
125}
Anders Lewisf4447b92017-06-23 15:53:59 -0700126BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_ALIGNED_ONEBUF;
Elliott Hughesfbe44ec2012-11-09 14:59:21 -0800127
Elliott Hughes281e06b2016-02-17 10:23:52 -0800128static void BM_string_memset(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +0100129 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700130 const size_t alignment = state.range(1);
131
132 std::vector<char> buf;
133 char* buf_aligned = GetAlignedPtr(&buf, alignment, nbytes + 1);
Elliott Hughes7be369d2012-11-08 15:37:43 -0800134
Elliott Hughes281e06b2016-02-17 10:23:52 -0800135 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700136 memset(buf_aligned, 0, nbytes);
Elliott Hughes7be369d2012-11-08 15:37:43 -0800137 }
138
Elliott Hughes281e06b2016-02-17 10:23:52 -0800139 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -0800140}
Anders Lewisf4447b92017-06-23 15:53:59 -0700141BENCHMARK(BM_string_memset)->AT_ALIGNED_ONEBUF;
Elliott Hughes7be369d2012-11-08 15:37:43 -0800142
Elliott Hughes281e06b2016-02-17 10:23:52 -0800143static void BM_string_strlen(benchmark::State& state) {
Martijn Coenenbe763d82016-11-14 14:16:08 +0100144 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700145 const size_t alignment = state.range(1);
146
147 std::vector<char> buf;
148 char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
149 buf_aligned[nbytes - 1] = '\0';
Elliott Hughes7be369d2012-11-08 15:37:43 -0800150
151 volatile int c __attribute__((unused)) = 0;
Elliott Hughes281e06b2016-02-17 10:23:52 -0800152 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700153 c += strlen(buf_aligned);
Elliott Hughes7be369d2012-11-08 15:37:43 -0800154 }
155
Elliott Hughes281e06b2016-02-17 10:23:52 -0800156 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
Elliott Hughes7be369d2012-11-08 15:37:43 -0800157}
Anders Lewisf4447b92017-06-23 15:53:59 -0700158BENCHMARK(BM_string_strlen)->AT_ALIGNED_ONEBUF;
Anders Lewisa99d0522017-06-12 11:24:01 -0700159
160static void BM_string_strcat_copy_only(benchmark::State& state) {
161 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700162 const size_t src_alignment = state.range(1);
163 const size_t dst_alignment = state.range(2);
164
165 std::vector<char> src;
166 std::vector<char> dst;
167 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
168 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes + 2);
169 src_aligned[nbytes - 1] = '\0';
170 dst_aligned[0] = 'y';
171 dst_aligned[1] = 'y';
172 dst_aligned[2] = '\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[2] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700177 }
178
179 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
180}
Anders Lewisf4447b92017-06-23 15:53:59 -0700181BENCHMARK(BM_string_strcat_copy_only)->AT_ALIGNED_TWOBUF;
Anders Lewisa99d0522017-06-12 11:24:01 -0700182
183static void BM_string_strcat_seek_only(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
188 std::vector<char> src;
189 std::vector<char> dst;
190 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, 3, 'x');
191 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes + 2, 'y');
192 src_aligned[2] = '\0';
193 dst_aligned[nbytes - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700194
195 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700196 strcat(dst_aligned, src_aligned);
197 dst_aligned[nbytes - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700198 }
199
200 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
201}
Anders Lewisf4447b92017-06-23 15:53:59 -0700202BENCHMARK(BM_string_strcat_seek_only)->AT_ALIGNED_TWOBUF;
Anders Lewisa99d0522017-06-12 11:24:01 -0700203
204static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) {
205 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700206 const size_t src_alignment = state.range(1);
207 const size_t dst_alignment = state.range(2);
208
209 std::vector<char> src;
210 std::vector<char> dst;
211 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes / 2, 'x');
212 char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
213 src_aligned[nbytes / 2 - 1] = '\0';
214 dst_aligned[nbytes / 2 - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700215
216 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700217 strcat(dst_aligned, src_aligned);
218 dst_aligned[nbytes / 2 - 1] = '\0';
Anders Lewisa99d0522017-06-12 11:24:01 -0700219 }
220
221 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
222}
Anders Lewisf4447b92017-06-23 15:53:59 -0700223BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_ALIGNED_TWOBUF;
Anders Lewis1c487e12017-06-12 12:33:06 -0700224
225static void BM_string_strcpy(benchmark::State& state) {
226 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700227 const size_t src_alignment = state.range(1);
228 const size_t dst_alignment = state.range(2);
229
230 std::vector<char> src;
231 std::vector<char> dst;
232 char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
233 char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
234 src_aligned[nbytes - 1] = '\0';
Anders Lewis1c487e12017-06-12 12:33:06 -0700235
236 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700237 strcpy(dst_aligned, src_aligned);
Anders Lewis1c487e12017-06-12 12:33:06 -0700238 }
239
240 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
241}
Anders Lewisf4447b92017-06-23 15:53:59 -0700242BENCHMARK(BM_string_strcpy)->AT_ALIGNED_TWOBUF;
Anders Lewis1c487e12017-06-12 12:33:06 -0700243
244static void BM_string_strcmp(benchmark::State& state) {
245 const size_t nbytes = state.range(0);
Anders Lewisf4447b92017-06-23 15:53:59 -0700246 const size_t s1_alignment = state.range(1);
247 const size_t s2_alignment = state.range(2);
248
249 std::vector<char> s1;
250 std::vector<char> s2;
251 char* s1_aligned = GetAlignedPtrFilled(&s1, s1_alignment, nbytes, 'x');
252 char* s2_aligned = GetAlignedPtrFilled(&s2, s2_alignment, nbytes, 'x');
253 s1_aligned[nbytes - 1] = '\0';
254 s2_aligned[nbytes - 1] = '\0';
Anders Lewis1c487e12017-06-12 12:33:06 -0700255
256 volatile int c __attribute__((unused));
257 while (state.KeepRunning()) {
Anders Lewisf4447b92017-06-23 15:53:59 -0700258 c = strcmp(s1_aligned, s2_aligned);
Anders Lewis1c487e12017-06-12 12:33:06 -0700259 }
260
261 state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
262}
Anders Lewisf4447b92017-06-23 15:53:59 -0700263BENCHMARK(BM_string_strcmp)->AT_ALIGNED_TWOBUF;