1 /*
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 
17 #include <stdint.h>
18 #include <string.h>
19 
20 #include <benchmark/Benchmark.h>
21 
22 #define KB 1024
23 #define MB 1024*KB
24 
25 #define AT_COMMON_SIZES \
26     Arg(8)->Arg(64)->Arg(512)->Arg(1*KB)->Arg(8*KB)->Arg(16*KB)->Arg(32*KB)->Arg(64*KB)
27 
28 // TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
29 
30 BENCHMARK_WITH_ARG(BM_string_memcmp, int)->AT_COMMON_SIZES;
Run(int iters,int nbytes)31 void BM_string_memcmp::Run(int iters, int nbytes) {
32   StopBenchmarkTiming();
33   char* src = new char[nbytes]; char* dst = new char[nbytes];
34   memset(src, 'x', nbytes);
35   memset(dst, 'x', nbytes);
36   StartBenchmarkTiming();
37 
38   volatile int c __attribute__((unused)) = 0;
39   for (int i = 0; i < iters; ++i) {
40     c += memcmp(dst, src, nbytes);
41   }
42 
43   StopBenchmarkTiming();
44   SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
45   delete[] src;
46   delete[] dst;
47 }
48 
49 BENCHMARK_WITH_ARG(BM_string_memcpy, int)->AT_COMMON_SIZES;
Run(int iters,int nbytes)50 void BM_string_memcpy::Run(int iters, int nbytes) {
51   StopBenchmarkTiming();
52   char* src = new char[nbytes]; char* dst = new char[nbytes];
53   memset(src, 'x', nbytes);
54   StartBenchmarkTiming();
55 
56   for (int i = 0; i < iters; ++i) {
57     memcpy(dst, src, nbytes);
58   }
59 
60   StopBenchmarkTiming();
61   SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
62   delete[] src;
63   delete[] dst;
64 }
65 
66 BENCHMARK_WITH_ARG(BM_string_memmove, int)->AT_COMMON_SIZES;
Run(int iters,int nbytes)67 void BM_string_memmove::Run(int iters, int nbytes) {
68   StopBenchmarkTiming();
69   char* buf = new char[nbytes + 64];
70   memset(buf, 'x', nbytes + 64);
71   StartBenchmarkTiming();
72 
73   for (int i = 0; i < iters; ++i) {
74     memmove(buf, buf + 1, nbytes); // Worst-case overlap.
75   }
76 
77   StopBenchmarkTiming();
78   SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
79   delete[] buf;
80 }
81 
82 BENCHMARK_WITH_ARG(BM_string_memset, int)->AT_COMMON_SIZES;
Run(int iters,int nbytes)83 void BM_string_memset::Run(int iters, int nbytes) {
84   StopBenchmarkTiming();
85   char* dst = new char[nbytes];
86   StartBenchmarkTiming();
87 
88   for (int i = 0; i < iters; ++i) {
89     memset(dst, 0, nbytes);
90   }
91 
92   StopBenchmarkTiming();
93   SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
94   delete[] dst;
95 }
96 
97 BENCHMARK_WITH_ARG(BM_string_strlen, int)->AT_COMMON_SIZES;
Run(int iters,int nbytes)98 void BM_string_strlen::Run(int iters, int nbytes) {
99   StopBenchmarkTiming();
100   char* s = new char[nbytes];
101   memset(s, 'x', nbytes);
102   s[nbytes - 1] = 0;
103   StartBenchmarkTiming();
104 
105   volatile int c __attribute__((unused)) = 0;
106   for (int i = 0; i < iters; ++i) {
107     c += strlen(s);
108   }
109 
110   StopBenchmarkTiming();
111   SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
112   delete[] s;
113 }
114