tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nanobenchmark_test.cc (2701B)


      1 // Copyright 2019 Google LLC
      2 // SPDX-License-Identifier: Apache-2.0
      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 #include "hwy/nanobenchmark.h"
     17 
     18 #include <stddef.h>
     19 #include <stdio.h>
     20 
     21 #include "hwy/tests/hwy_gtest.h"
     22 #include "hwy/tests/test_util-inl.h"
     23 
     24 namespace hwy {
     25 namespace {
     26 
     27 // Governs duration of test; avoid timeout in debug builds.
     28 #if HWY_IS_DEBUG_BUILD
     29 constexpr size_t kMaxEvals = 3;
     30 #else
     31 constexpr size_t kMaxEvals = 4;
     32 #endif
     33 
     34 FuncOutput Div(const void*, FuncInput in) {
     35  // Here we're measuring the throughput because benchmark invocations are
     36  // independent. Any dividend will do; the divisor is nonzero.
     37  return 0xFFFFF / in;
     38 }
     39 
     40 template <size_t N>
     41 void MeasureDiv(const FuncInput (&inputs)[N]) {
     42  printf("Measuring integer division (output on final two lines)\n");
     43  Result results[N];
     44  Params params;
     45  params.max_evals = kMaxEvals;
     46  const size_t num_results = Measure(&Div, nullptr, inputs, N, results, params);
     47  for (size_t i = 0; i < num_results; ++i) {
     48    printf("%5d: %6.2f ticks; MAD=%4.2f%%\n",
     49           static_cast<int>(results[i].input), results[i].ticks,
     50           results[i].variability * 100.0);
     51  }
     52 }
     53 
     54 RandomState rng;
     55 
     56 // A function whose runtime depends on rng.
     57 FuncOutput Random(const void* /*arg*/, FuncInput in) {
     58  const size_t r = rng() & 0xF;
     59  FuncOutput ret = static_cast<FuncOutput>(in);
     60  for (size_t i = 0; i < r; ++i) {
     61    ret /= ((rng() & 1) + 2);
     62  }
     63  return ret;
     64 }
     65 
     66 // Ensure the measured variability is high.
     67 template <size_t N>
     68 void MeasureRandom(const FuncInput (&inputs)[N]) {
     69  Result results[N];
     70  Params p;
     71  p.max_evals = kMaxEvals;
     72  p.verbose = false;
     73  const size_t num_results = Measure(&Random, nullptr, inputs, N, results, p);
     74  for (size_t i = 0; i < num_results; ++i) {
     75    HWY_ASSERT(results[i].variability > 1E-3);
     76  }
     77 }
     78 
     79 TEST(NanobenchmarkTest, RunTest) {
     80  const int unpredictable = Unpredictable1();  // == 1, unknown to compiler.
     81  static const FuncInput inputs[] = {static_cast<FuncInput>(unpredictable) + 2,
     82                                     static_cast<FuncInput>(unpredictable + 9)};
     83 
     84  MeasureDiv(inputs);
     85  MeasureRandom(inputs);
     86 }
     87 
     88 }  // namespace
     89 }  // namespace hwy
     90 
     91 HWY_TEST_MAIN();