• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cstdlib"
17 #include "cstdio"
18 #include "cstring"
19 #include "fcntl.h"
20 #include "unistd.h"
21 #include "cwchar"
22 #include "clocale"
23 #include "util.h"
24 
25 using namespace std;
26 
27 using Nier = struct {
28     char name[20];
29     int age;
30 };
31 
32 static const vector<int> memalignLength {
33     8,
34     16,
35     64,
36     1 * K,
37     4 * K,
38     64 * K,
39     256 * K,
40     1 * M,
41     4 * M,
42     64 * M,
43     256 * M,
44     1 * G,
45 };
46 
47 static const vector<int> memalignAlign {
48     8,
49     16,
50     64,
51     256,
52     1 * K,
53     4 * K,
54     64 * K,
55     256 * K,
56     1 * M,
57 };
58 
PrepareArgsMemalign(benchmark::internal::Benchmark * b)59 static void PrepareArgsMemalign(benchmark::internal::Benchmark* b)
60 {
61     for (auto a : memalignAlign) {
62         for (auto l : memalignLength) {
63             if (l >= a && l % a == 0) {
64                 b->Args({a, l});
65             }
66         }
67     }
68 }
69 
CompareInt(const void * a,const void * b)70 int CompareInt(const void *a, const void *b)
71 {
72     int c = *(int *)a;
73     int d = *(int *)b;
74     if (c < d) {
75         return -1;
76     } else if (c > d) {
77         return 1;
78     } else {
79         return 0;
80     }
81 }
82 
CompareDouble(const void * a,const void * b)83 int CompareDouble(const void *a, const void *b)
84 {
85     double c = *(double *)a;
86     double d = *(double *)b;
87     if (c == d) {
88         return 0;
89     } else if (c > d) {
90         return 1;
91     } else {
92         return -1;
93     }
94 }
95 
CompareString(const void * a,const void * b)96 int CompareString(const void *a, const void *b)
97 {
98     const char* c = (char *)a;
99     const char* d = (char *)b;
100     return strcmp(c, d);
101 }
102 
CompareStruct(const void * a,const void * b)103 int CompareStruct(const void *a, const void *b)
104 {
105     return strcmp(((Nier *)a)->name, ((Nier *)b)->name);
106 }
107 
InitRandomArray(int * arr,size_t n)108 void InitRandomArray(int *arr, size_t n)
109 {
110     for (size_t i = 0; i < n; i++) {
111         arr[i] = rand() % (2 * n);
112     }
113 }
114 
115 // Convert the string pointed to by str to floating point
Bm_function_Strtod(benchmark::State & state)116 static void Bm_function_Strtod(benchmark::State &state)
117 {
118     const char *var[] = { "+2.86500000e+01", "3.1415", "29",
119                           "-123.456", "1.23e5", "0x1.2p3",
120                           "-inf", "123foo" };
121     const char *str = var[state.range(0)];
122     char *ptr;
123     for (auto _ : state) {
124         benchmark::DoNotOptimize(strtod(str, &ptr));
125     }
126 }
127 
Bm_function_Strtof(benchmark::State & state)128 static void Bm_function_Strtof(benchmark::State &state)
129 {
130      const char *var[] = {"+2.86500000e+01", "3.1415", "29",
131                           "-123.456", "1.23e5", "0x1.2p3",
132                           "-inf", "123foo"};
133     const char *str = var[state.range(0)];
134     char *ptr;
135     for (auto _ : state) {
136         benchmark::DoNotOptimize(strtof(str, &ptr));
137     }
138 }
139 
Bm_function_Strtold(benchmark::State & state)140 static void Bm_function_Strtold(benchmark::State &state)
141 {
142      const char *var[] = {"+2.86500000e+01", "3.1415", "29",
143                           "-123.456", "1.23e5", "0x1.2p3",
144                           "-inf", "123foo"};
145     const char *str = var[state.range(0)];
146     char *ptr;
147     for (auto _ : state) {
148         benchmark::DoNotOptimize(strtold(str, &ptr));
149     }
150 }
151 
152 // Used to sort elements in an array
153 // int type
Bm_function_Qsortint(benchmark::State & state)154 static void Bm_function_Qsortint(benchmark::State &state)
155 {
156     for (auto _ : state) {
157         int arr[] = { 12, 89, 5, 3, 7, 1, 9, 2, 6 };
158         int n = sizeof(arr) / sizeof(arr[0]);
159         qsort(arr, n, sizeof(int), CompareInt);
160     }
161 }
162 
163 // double type
Bm_function_Qsortdouble(benchmark::State & state)164 static void Bm_function_Qsortdouble(benchmark::State &state)
165 {
166     for (auto _ : state) {
167         double arr[] = { 34.541, 5.32, 3.56, 7.897, 1.2324, 9.34543, 5.324, 98.543, 34.665 };
168         int n = sizeof(arr) / sizeof(arr[0]);
169         qsort(arr, n, sizeof(double), CompareDouble);
170     }
171 }
172 
173 // string type
Bm_function_Qsortstring(benchmark::State & state)174 static void Bm_function_Qsortstring(benchmark::State &state)
175 {
176     for (auto _ : state) {
177         const char *arr[] = { "nihuangela", "xiaozhenhuniang", "our story",
178                               "a language", "love", "qluhanagala",
179                               "for elun", "sakuruwuma", "benchmark_musl" };
180         int n = sizeof(arr) / sizeof(arr[0]);
181         qsort(arr, n, sizeof(char *), CompareString);
182     }
183 }
184 
185 // struct type
Bm_function_Qsortstruct(benchmark::State & state)186 static void Bm_function_Qsortstruct(benchmark::State &state)
187 {
188     const int len = 9;
189     for (auto _ : state) {
190         Nier nidate[len] = { {"Meihuagao", 23}, {"Sdifenzhou", 68}, {"Amusterlang", 99},
191                              {"elun", 56}, {"yishinuala", 120}, {"huajiahaochi", 22},
192                              {"lunala", 66}, {"cocolou", 77}, {"xinnoqikala", 55} };
193         qsort(nidate, len, sizeof(Nier), CompareStruct);
194     }
195 }
196 
Bm_function_Qsort_random(benchmark::State & state)197 static void Bm_function_Qsort_random(benchmark::State &state)
198 {
199     srand(1);
200     int n = state.range(0);
201     int *arr1 = new int[n];
202     int *arr2 = new int[n];
203     InitRandomArray(arr1, n);
204 
205     for (auto _ : state)
206     {
207         state.PauseTiming();
208         memcpy(arr2, arr1, n);
209         state.ResumeTiming();
210         qsort(arr2, n, sizeof(int), CompareInt);
211     }
212 
213     delete[] arr1;
214     delete[] arr2;
215 }
216 
Bm_function_Getenv_TZ(benchmark::State & state)217 static void Bm_function_Getenv_TZ(benchmark::State &state)
218 {
219     for (auto _ : state) {
220         benchmark::DoNotOptimize(getenv("TZ"));
221     }
222 }
223 
Bm_function_Getenv_LD_LIBRARY_PATH(benchmark::State & state)224 static void Bm_function_Getenv_LD_LIBRARY_PATH(benchmark::State &state)
225 {
226     for (auto _ : state) {
227         benchmark::DoNotOptimize(getenv("LD_LIBRARY_PATH"));
228     }
229 }
230 
Bm_function_Getenv_LD_PRELOAD(benchmark::State & state)231 static void Bm_function_Getenv_LD_PRELOAD(benchmark::State &state)
232 {
233     for (auto _ : state) {
234         benchmark::DoNotOptimize(getenv("LD_PRELOAD"));
235     }
236 }
237 
Bm_function_Getenv_LC_ALL(benchmark::State & state)238 static void Bm_function_Getenv_LC_ALL(benchmark::State &state)
239 {
240     for (auto _ : state) {
241         benchmark::DoNotOptimize(getenv("LC_ALL"));
242     }
243 }
244 
Bm_function_Getenv_LOGNAME(benchmark::State & state)245 static void Bm_function_Getenv_LOGNAME(benchmark::State &state)
246 {
247     for (auto _ : state) {
248         benchmark::DoNotOptimize(getenv("LOGNAME"));
249     }
250 }
251 
252 // Converts any relative path to an absolute path
Bm_function_Realpath(benchmark::State & state)253 static void Bm_function_Realpath(benchmark::State &state)
254 {
255     const int bufferLen = 4096;
256     const char *realpathvariable[] = { "./log", "../dev", "log/hilog", "../dev/zero", "/dev" };
257     const char *path = realpathvariable[state.range(0)];
258     char resolvedPath[bufferLen];
259     for (auto _ : state) {
260         benchmark::DoNotOptimize(realpath(path, resolvedPath));
261     }
262 }
263 
Bm_function_Posix_Memalign(benchmark::State & state)264 static void Bm_function_Posix_Memalign(benchmark::State &state)
265 {
266     size_t align = state.range(0);
267     size_t length = state.range(1);
268     for (auto _ : state) {
269         void *buf = nullptr;
270         int ret = posix_memalign(&buf, align, length);
271         if (ret) {
272             perror("posix_memalign failed");
273         }
274 
275         state.PauseTiming();
276         free(buf);
277         state.ResumeTiming();
278     }
279 }
280 
Bm_function_Mkostemps(benchmark::State & state)281 static void Bm_function_Mkostemps(benchmark::State &state)
282 {
283     char fileTemplate[] = "/tmp/mkostemps-XXXXXX-test";
284     for (auto _ : state) {
285         int fd = mkostemps(fileTemplate, 5, O_SYNC);
286         if (fd >= 0) {
287             unlink(fileTemplate);
288             close(fd);
289         }
290     }
291 }
292 
293 // Generate a random number seed and receive a sequence of random numbers
Bm_function_Srand48_Lrand48(benchmark::State & state)294 static void Bm_function_Srand48_Lrand48(benchmark::State &state)
295 {
296     for (auto _ : state) {
297         srand48(time(nullptr));
298         benchmark::DoNotOptimize(lrand48());
299     }
300 }
301 
302 // Customize the value of the environment variable and delete it
Bm_function_Putenv_Unsetenv(benchmark::State & state)303 static void Bm_function_Putenv_Unsetenv(benchmark::State &state)
304 {
305     const char *putpath[] = { "TEST_A=/usr/local/myapp", "TEST_B=/bin/yes", "TEST_C=/usr/local/bin:/usr/bin:/bin",
306                               "TEST_D=vim", "TEST_E=hello", "TEST_F=en_US.UTF-8", "TEST_G=myname",
307                               "TEST_H=nichenzhan" };
308     const char *unsetpath[] = { "TEST_A", "TEST_B", "TEST_C", "TEST_D",
309                                 "TEST_E", "TEST_F", "TEST_G", "TEST_H" };
310     const char *a = putpath[state.range(0)];
311     const char *b = unsetpath[state.range(0)];
312     for (auto _ : state) {
313         benchmark::DoNotOptimize(putenv((char*)a));
314         benchmark::DoNotOptimize(unsetenv(b));
315     }
316 }
317 
Bm_function_Wcstombs(benchmark::State & state)318 static void Bm_function_Wcstombs(benchmark::State &state)
319 {
320     setlocale(LC_ALL, "");
321     const wchar_t wstr[] = L"z\u00df\u6c34\U0001f34c";
322     size_t len = wcslen(wstr);
323     char *str = (char*)malloc(sizeof(char) * (len + 1));
324     for (auto _ : state) {
325         benchmark::DoNotOptimize(wcstombs(str, wstr, len));
326     }
327     free(str);
328 }
329 
ExitFunc()330 void ExitFunc(){};
Bm_function_cxa_atexit(benchmark::State & state)331 static void Bm_function_cxa_atexit(benchmark::State &state)
332 {
333     for (auto _ : state) {
334         benchmark::DoNotOptimize(atexit(ExitFunc));
335     }
336 }
337 
Bm_function_Srandom(benchmark::State & state)338 static void Bm_function_Srandom(benchmark::State &state)
339 {
340     unsigned int seed = static_cast<unsigned int>(time(nullptr));
341     for (auto _ : state) {
342         srandom(seed);
343     }
344 }
345 
346 MUSL_BENCHMARK_WITH_ARG(Bm_function_Strtod, "BENCHMARK_8");
347 MUSL_BENCHMARK_WITH_ARG(Bm_function_Strtof, "BENCHMARK_8");
348 MUSL_BENCHMARK_WITH_ARG(Bm_function_Strtold, "BENCHMARK_8");
349 MUSL_BENCHMARK(Bm_function_Qsortint);
350 MUSL_BENCHMARK(Bm_function_Qsortdouble);
351 MUSL_BENCHMARK(Bm_function_Qsortstring);
352 MUSL_BENCHMARK(Bm_function_Qsortstruct);
353 MUSL_BENCHMARK_WITH_ARG(Bm_function_Qsort_random, "COMMON_ARGS");
354 MUSL_BENCHMARK_WITH_ARG(Bm_function_Realpath, "BENCHMARK_5");
355 MUSL_BENCHMARK(Bm_function_Getenv_TZ);
356 MUSL_BENCHMARK(Bm_function_Getenv_LD_LIBRARY_PATH);
357 MUSL_BENCHMARK(Bm_function_Getenv_LD_PRELOAD);
358 MUSL_BENCHMARK(Bm_function_Getenv_LC_ALL);
359 MUSL_BENCHMARK(Bm_function_Getenv_LOGNAME);
360 MUSL_BENCHMARK_WITH_APPLY(Bm_function_Posix_Memalign, PrepareArgsMemalign);
361 MUSL_BENCHMARK(Bm_function_Mkostemps);
362 MUSL_BENCHMARK(Bm_function_Srand48_Lrand48);
363 MUSL_BENCHMARK_WITH_ARG(Bm_function_Putenv_Unsetenv, "BENCHMARK_8");
364 MUSL_BENCHMARK(Bm_function_Wcstombs);
365 MUSL_BENCHMARK(Bm_function_cxa_atexit);
366 MUSL_BENCHMARK(Bm_function_Srandom);
367