Home | History | Annotate | Download | only in benchmarks
      1 /*
      2  * Copyright (C) 2017 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 <err.h>
     18 #include <langinfo.h>
     19 #include <locale.h>
     20 #include <malloc.h>
     21 #include <stdlib.h>
     22 #include <unistd.h>
     23 
     24 #include <benchmark/benchmark.h>
     25 #include "util.h"
     26 
     27 #if defined(__BIONIC__)
     28 
     29 #else
     30 #endif
     31 
     32 static __always_inline void MakeAllocationResident(void* ptr, size_t nbytes, int pagesize) {
     33   uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
     34   for (size_t i = 0; i < nbytes; i += pagesize) {
     35     data[i] = 1;
     36   }
     37 }
     38 
     39 static void MallocFree(benchmark::State& state) {
     40   const size_t nbytes = state.range(0);
     41   int pagesize = getpagesize();
     42 
     43   for (auto _ : state) {
     44     void* ptr;
     45     benchmark::DoNotOptimize(ptr = malloc(nbytes));
     46     MakeAllocationResident(ptr, nbytes, pagesize);
     47     free(ptr);
     48   }
     49 
     50   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
     51 }
     52 
     53 static void BM_stdlib_malloc_free_default(benchmark::State& state) {
     54 #if defined(__BIONIC__)
     55   // The default is expected to be a zero decay time.
     56   mallopt(M_DECAY_TIME, 0);
     57 #endif
     58 
     59   MallocFree(state);
     60 }
     61 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_default, "AT_COMMON_SIZES");
     62 
     63 #if defined(__BIONIC__)
     64 static void BM_stdlib_malloc_free_decay1(benchmark::State& state) {
     65   mallopt(M_DECAY_TIME, 1);
     66 
     67   MallocFree(state);
     68 
     69   mallopt(M_DECAY_TIME, 0);
     70 }
     71 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_decay1, "AT_COMMON_SIZES");
     72 #endif
     73 
     74 static void MallocMultiple(benchmark::State& state, size_t nbytes, size_t numAllocs) {
     75   int pagesize = getpagesize();
     76   void* ptrs[numAllocs];
     77   for (auto _ : state) {
     78     for (size_t i = 0; i < numAllocs; i++) {
     79       benchmark::DoNotOptimize(ptrs[i] = reinterpret_cast<uint8_t*>(malloc(nbytes)));
     80       MakeAllocationResident(ptrs[i], nbytes, pagesize);
     81     }
     82     state.PauseTiming(); // Stop timers while freeing pointers.
     83     for (size_t i = 0; i < numAllocs; i++) {
     84       free(ptrs[i]);
     85     }
     86     state.ResumeTiming();
     87   }
     88 
     89   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes) * numAllocs);
     90 }
     91 
     92 void BM_stdlib_malloc_forty_default(benchmark::State& state) {
     93 
     94 #if defined(__BIONIC__)
     95   // The default is expected to be a zero decay time.
     96   mallopt(M_DECAY_TIME, 0);
     97 #endif
     98 
     99   MallocMultiple(state, state.range(0), 40);
    100 }
    101 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_default, "AT_COMMON_SIZES");
    102 
    103 #if defined(__BIONIC__)
    104 void BM_stdlib_malloc_forty_decay1(benchmark::State& state) {
    105   mallopt(M_DECAY_TIME, 1);
    106 
    107   MallocMultiple(state, state.range(0), 40);
    108 
    109   mallopt(M_DECAY_TIME, 0);
    110 }
    111 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_decay1, "AT_COMMON_SIZES");
    112 #endif
    113 
    114 void BM_stdlib_malloc_multiple_8192_allocs_default(benchmark::State& state) {
    115 #if defined(__BIONIC__)
    116   // The default is expected to be a zero decay time.
    117   mallopt(M_DECAY_TIME, 0);
    118 #endif
    119 
    120   MallocMultiple(state, 8192, state.range(0));
    121 }
    122 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_default, "AT_SMALL_SIZES");
    123 
    124 #if defined(__BIONIC__)
    125 void BM_stdlib_malloc_multiple_8192_allocs_decay1(benchmark::State& state) {
    126   mallopt(M_DECAY_TIME, 1);
    127 
    128   MallocMultiple(state, 8192, state.range(0));
    129 
    130   mallopt(M_DECAY_TIME, 0);
    131 }
    132 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_decay1, "AT_SMALL_SIZES");
    133 #endif
    134 
    135 static void BM_stdlib_mbstowcs(benchmark::State& state) {
    136   const size_t buf_alignment = state.range(0);
    137   const size_t widebuf_alignment = state.range(1);
    138 
    139   std::vector<char> buf;
    140   std::vector<wchar_t> widebuf;
    141 
    142   setlocale(LC_CTYPE, "C.UTF-8")
    143   || setlocale(LC_CTYPE, "en_US.UTF-8")
    144   || setlocale(LC_CTYPE, "en_GB.UTF-8")
    145   || setlocale(LC_CTYPE, "en.UTF-8")
    146   || setlocale(LC_CTYPE, "de_DE-8")
    147   || setlocale(LC_CTYPE, "fr_FR-8");
    148   if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
    149     errx(1, "ERROR: unable to set locale in BM_stdlib_mbstowcs");
    150   }
    151 
    152   char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
    153   wchar_t* widebuf_aligned = GetAlignedPtr(&widebuf, widebuf_alignment, 500000);
    154   size_t i, j, k, l;
    155   l = 0;
    156   for (i=0xc3; i<0xe0; i++)
    157     for (j=0x80; j<0xc0; j++)
    158       buf[l++] = i, buf[l++] = j;
    159   for (i=0xe1; i<0xed; i++)
    160     for (j=0x80; j<0xc0; j++)
    161       for (k=0x80; k<0xc0; k++)
    162         buf[l++] = i, buf[l++] = j, buf[l++] = k;
    163   for (i=0xf1; i<0xf4; i++)
    164     for (j=0x80; j<0xc0; j++)
    165       for (k=0x80; k<0xc0; k++)
    166         buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
    167   buf[l++] = 0;
    168 
    169   volatile size_t c __attribute__((unused)) = 0;
    170   for (auto _ : state) {
    171     c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
    172   }
    173 
    174   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
    175 }
    176 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbstowcs, "0 0");
    177 
    178 static void BM_stdlib_mbrtowc(benchmark::State& state) {
    179   const size_t buf_alignment = state.range(0);
    180 
    181   std::vector<char> buf;
    182 
    183   setlocale(LC_CTYPE, "C.UTF-8")
    184   || setlocale(LC_CTYPE, "en_US.UTF-8")
    185   || setlocale(LC_CTYPE, "en_GB.UTF-8")
    186   || setlocale(LC_CTYPE, "en.UTF-8")
    187   || setlocale(LC_CTYPE, "de_DE-8")
    188   || setlocale(LC_CTYPE, "fr_FR-8");
    189   if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
    190     errx(1, "ERROR: unable to set locale in BM_stdlib_mbrtowc");
    191   }
    192 
    193   char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
    194   size_t i, j, k, l;
    195   l = 0;
    196   for (i=0xc3; i<0xe0; i++)
    197     for (j=0x80; j<0xc0; j++)
    198       buf[l++] = i, buf[l++] = j;
    199   for (i=0xe1; i<0xed; i++)
    200     for (j=0x80; j<0xc0; j++)
    201       for (k=0x80; k<0xc0; k++)
    202         buf[l++] = i, buf[l++] = j, buf[l++] = k;
    203   for (i=0xf1; i<0xf4; i++)
    204     for (j=0x80; j<0xc0; j++)
    205       for (k=0x80; k<0xc0; k++)
    206         buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
    207   buf[l++] = 0;
    208 
    209   wchar_t wc = 0;
    210   for (auto _ : state) {
    211     for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, nullptr)) {
    212     }
    213   }
    214 
    215   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
    216 }
    217 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc, "0");
    218 
    219 void BM_stdlib_atoi(benchmark::State& state) {
    220   for (auto _ : state) {
    221     benchmark::DoNotOptimize(atoi(" -123"));
    222   }
    223 }
    224 BIONIC_BENCHMARK(BM_stdlib_atoi);
    225 
    226 void BM_stdlib_atol(benchmark::State& state) {
    227   for (auto _ : state) {
    228     benchmark::DoNotOptimize(atol(" -123"));
    229   }
    230 }
    231 BIONIC_BENCHMARK(BM_stdlib_atol);
    232 
    233 void BM_stdlib_strtol(benchmark::State& state) {
    234   for (auto _ : state) {
    235     benchmark::DoNotOptimize(strtol(" -123", nullptr, 0));
    236   }
    237 }
    238 BIONIC_BENCHMARK(BM_stdlib_strtol);
    239 
    240 void BM_stdlib_strtoll(benchmark::State& state) {
    241   for (auto _ : state) {
    242     benchmark::DoNotOptimize(strtoll(" -123", nullptr, 0));
    243   }
    244 }
    245 BIONIC_BENCHMARK(BM_stdlib_strtoll);
    246 
    247 void BM_stdlib_strtoul(benchmark::State& state) {
    248   for (auto _ : state) {
    249     benchmark::DoNotOptimize(strtoul(" -123", nullptr, 0));
    250   }
    251 }
    252 BIONIC_BENCHMARK(BM_stdlib_strtoul);
    253 
    254 void BM_stdlib_strtoull(benchmark::State& state) {
    255   for (auto _ : state) {
    256     benchmark::DoNotOptimize(strtoull(" -123", nullptr, 0));
    257   }
    258 }
    259 BIONIC_BENCHMARK(BM_stdlib_strtoull);
    260 
    261