diff options
author | Christopher Ferris <cferris@google.com> | 2017-08-08 01:20:46 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-08-08 01:20:46 +0000 |
commit | ebbbe292bd2657b98007f3b6d0405686c1c646b8 (patch) | |
tree | 7725096a817a36ded544e815c507be40c88a9d23 | |
parent | 8aa387fbee2e741e00d34290945b67ab42bb10ec (diff) | |
parent | a7b0f8899790198cd9e72950f481679fe31e1a92 (diff) | |
download | bionic-ebbbe292bd2657b98007f3b6d0405686c1c646b8.tar.gz |
Merge "Implement interface for bionic benchmarks."
-rw-r--r-- | benchmarks/Android.bp | 10 | ||||
-rw-r--r-- | benchmarks/atomic_benchmark.cpp | 24 | ||||
-rw-r--r-- | benchmarks/bionic_benchmarks.cpp | 385 | ||||
-rw-r--r-- | benchmarks/math_benchmark.cpp | 40 | ||||
-rw-r--r-- | benchmarks/property_benchmark.cpp | 14 | ||||
-rw-r--r-- | benchmarks/pthread_benchmark.cpp | 29 | ||||
-rw-r--r-- | benchmarks/semaphore_benchmark.cpp | 11 | ||||
-rw-r--r-- | benchmarks/stdio_benchmark.cpp | 19 | ||||
-rw-r--r-- | benchmarks/string_benchmark.cpp | 46 | ||||
-rw-r--r-- | benchmarks/suites/full.xml | 267 | ||||
-rw-r--r-- | benchmarks/suites/host.xml | 244 | ||||
-rw-r--r-- | benchmarks/suites/test_alignment.xml | 50 | ||||
-rw-r--r-- | benchmarks/suites/test_from_each.xml | 30 | ||||
-rw-r--r-- | benchmarks/suites/test_full.xml | 261 | ||||
-rw-r--r-- | benchmarks/suites/test_medium.xml | 16 | ||||
-rw-r--r-- | benchmarks/suites/test_small.xml | 11 | ||||
-rw-r--r-- | benchmarks/tests/interface_test.cpp | 526 | ||||
-rw-r--r-- | benchmarks/time_benchmark.cpp | 15 | ||||
-rw-r--r-- | benchmarks/unistd_benchmark.cpp | 11 | ||||
-rw-r--r-- | benchmarks/util.cpp | 12 | ||||
-rw-r--r-- | benchmarks/util.h | 36 |
21 files changed, 1930 insertions, 127 deletions
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp index 0edba659a..fae6f20af 100644 --- a/benchmarks/Android.bp +++ b/benchmarks/Android.bp @@ -25,6 +25,7 @@ cc_defaults { "-Wunused", ], srcs: [ + "bionic_benchmarks.cpp", "atomic_benchmark.cpp", "math_benchmark.cpp", "property_benchmark.cpp", @@ -35,7 +36,11 @@ cc_defaults { "time_benchmark.cpp", "unistd_benchmark.cpp", ], - static_libs: ["libBionicBenchmarksUtils"], + shared_libs: ["libtinyxml2"], + static_libs: [ + "libbase", + "libBionicBenchmarksUtils", + ], } cc_defaults { @@ -54,6 +59,7 @@ cc_defaults { cc_benchmark { name: "bionic-benchmarks", defaults: ["bionic-benchmarks-defaults"], + data: ["suites/*"], } // We don't build a static benchmark executable because it's not usually @@ -87,6 +93,8 @@ cc_test { defaults: ["bionic-benchmarks-extras-defaults"], srcs: [ "tests/benchmark_test.cpp", + "tests/interface_test.cpp", ], static_libs: ["libBionicBenchmarksUtils"], + data: ["suites/test_*.xml"], } diff --git a/benchmarks/atomic_benchmark.cpp b/benchmarks/atomic_benchmark.cpp index 66a0120a1..a584dce2d 100644 --- a/benchmarks/atomic_benchmark.cpp +++ b/benchmarks/atomic_benchmark.cpp @@ -20,10 +20,12 @@ // Expected mappings from C++ atomics to hardware primitives can be found at // http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html . -#include <benchmark/benchmark.h> #include <atomic> #include <mutex> +#include <benchmark/benchmark.h> +#include "util.h" + // We time atomic operations separated by a volatile (not atomic!) increment. This ensures // that the compiler emits memory instructions (e.g. load or store) prior to any fence or the // like. That in turn ensures that the CPU has outstanding memory operations when the fence @@ -48,7 +50,7 @@ void BM_empty(benchmark::State& state) { ++counter; } } -BENCHMARK(BM_empty); +BIONIC_BENCHMARK(BM_empty); static void BM_load_relaxed(benchmark::State& state) { unsigned result = 0; @@ -58,7 +60,7 @@ static void BM_load_relaxed(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_load_relaxed); +BIONIC_BENCHMARK(BM_load_relaxed); static void BM_load_acquire(benchmark::State& state) { unsigned result = 0; @@ -68,7 +70,7 @@ static void BM_load_acquire(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_load_acquire); +BIONIC_BENCHMARK(BM_load_acquire); static void BM_store_release(benchmark::State& state) { int i = counter; @@ -77,7 +79,7 @@ static void BM_store_release(benchmark::State& state) { ++counter; } } -BENCHMARK(BM_store_release); +BIONIC_BENCHMARK(BM_store_release); static void BM_store_seq_cst(benchmark::State& state) { int i = counter; @@ -86,7 +88,7 @@ static void BM_store_seq_cst(benchmark::State& state) { ++counter; } } -BENCHMARK(BM_store_seq_cst); +BIONIC_BENCHMARK(BM_store_seq_cst); static void BM_fetch_add_relaxed(benchmark::State& state) { unsigned result = 0; @@ -96,7 +98,7 @@ static void BM_fetch_add_relaxed(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_fetch_add_relaxed); +BIONIC_BENCHMARK(BM_fetch_add_relaxed); static void BM_fetch_add_seq_cst(benchmark::State& state) { unsigned result = 0; @@ -106,7 +108,7 @@ static void BM_fetch_add_seq_cst(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_fetch_add_seq_cst); +BIONIC_BENCHMARK(BM_fetch_add_seq_cst); // The fence benchmarks include a relaxed load to make it much harder to optimize away // the fence. @@ -120,7 +122,7 @@ static void BM_acquire_fence(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_acquire_fence); +BIONIC_BENCHMARK(BM_acquire_fence); static void BM_seq_cst_fence(benchmark::State& state) { unsigned result = 0; @@ -131,7 +133,7 @@ static void BM_seq_cst_fence(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_seq_cst_fence); +BIONIC_BENCHMARK(BM_seq_cst_fence); // For comparison, also throw in a critical section version: @@ -145,4 +147,4 @@ static void BM_fetch_add_cs(benchmark::State& state) { } sink = result; } -BENCHMARK(BM_fetch_add_cs); +BIONIC_BENCHMARK(BM_fetch_add_cs); diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp new file mode 100644 index 000000000..7f91b7444 --- /dev/null +++ b/benchmarks/bionic_benchmarks.cpp @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <getopt.h> +#include <math.h> +#include <sys/resource.h> + +#include <map> +#include <mutex> +#include <sstream> +#include <string> +#include <vector> + +#include "android-base/strings.h" +#include <benchmark/benchmark.h> +#include <tinyxml2.h> +#include "util.h" + +std::map<std::string, benchmark_func_t> g_str_to_func; + +std::mutex g_map_lock; + +static struct option g_long_options[] = +{ + {"bionic_cpu", required_argument, 0, 'c'}, + {"bionic_xml", required_argument, 0, 'x'}, + {"bionic_iterations", required_argument, 0, 'i'}, + {"bionic_extra", required_argument, 0, 'a'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}, +}; + +typedef std::vector<std::vector<int>> args_vector_t; + +void Usage() { + printf("Usage:\n"); + printf("bionic_benchmarks [--bionic_cpu=<cpu_to_isolate>] [--bionic_xml=<path_to_xml>]\n"); + printf(" [--bionic_iterations=<num_iter>]\n"); + printf(" [--bionic_extra=\"<fn_name> <arg1> <arg 2> ... \n]"); + printf(" [<Google benchmark flags>]\n"); + printf("Google benchmark flags:\n"); + + int fake_argc = 2; + char argv0[] = "bionic_benchmarks"; + char argv1[] = "--help"; + char* fake_argv[3] {argv0, argv1, NULL}; + benchmark::Initialize(&fake_argc, fake_argv); + abort(); +} + +// This function removes any bionic benchmarks command line arguments by checking them +// against g_long_options. It fills new_argv with the filtered args. +void SanitizeOpts(int argc, char** argv, std::vector<char*>* new_argv) { + // TO THOSE ADDING OPTIONS: This currently doesn't support optional arguments. + (*new_argv)[0] = argv[0]; + for (int i = 1; i < argc; ++i) { + char* optarg = argv[i]; + size_t opt_idx = 0; + + // Iterate through g_long_options until either we hit the end or we have a match. + for (opt_idx = 0; g_long_options[opt_idx].name && + strncmp(g_long_options[opt_idx].name, optarg + 2, + strlen(g_long_options[opt_idx].name)); ++opt_idx) { + } + + if (!g_long_options[opt_idx].name) { + new_argv->push_back(optarg); + } else { + if (g_long_options[opt_idx].has_arg == required_argument) { + // If the arg was passed in with an =, it spans one char *. + // Otherwise, we skip a spot for the argument. + if (!strchr(optarg, '=')) { + i++; + } + } + } + } + new_argv->push_back(0); +} + +bench_opts_t ParseOpts(int argc, char** argv) { + bench_opts_t opts; + int opt; + int option_index = 0; + + opts.cpu_to_lock = LONG_MAX; + opts.num_iterations = 0; + + // To make this parser handle the benchmark options silently: + extern int opterr; + opterr = 0; + + while ((opt = getopt_long(argc, argv, "c:x:i:a:h", g_long_options, &option_index)) != -1) { + if (opt == -1) { + break; + } + switch (opt) { + case 'c': + if (*optarg) { + char* check_null; + opts.cpu_to_lock = strtol(optarg, &check_null, 10); + if (*check_null) { + printf("ERROR: Args %s is not a valid integer.\n", optarg); + abort(); + } + } else { + printf("ERROR: no argument specified for bionic_cpu\n"); + Usage(); + } + break; + case 'x': + if (*optarg) { + opts.xmlpath = optarg; + } else { + printf("ERROR: no argument specified for bionic_xml\n"); + Usage(); + } + break; + case 'a': + if (*optarg) { + opts.extra_benchmarks.push_back(optarg); + } else { + printf("ERROR: no argument specified for bionic_extra\n"); + Usage(); + } + break; + case 'i': + if (*optarg){ + char* check_null; + opts.num_iterations = strtol(optarg, &check_null, 10); + if (*check_null != '\0') { + printf("ERROR: Args %s is not a valid integer.\n", optarg); + abort(); + } + } else { + printf("ERROR: no argument specified for bionic_iterations\n"); + Usage(); + } + break; + case 'h': + Usage(); + break; + case '?': + break; + default: + abort(); + } + } + return opts; +} + +// This is a wrapper for every function call for per-benchmark cpu pinning. +void LockAndRun(benchmark::State& state, benchmark_func_t func_to_bench, long cpu_to_lock) { + if (cpu_to_lock != LONG_MAX) LockToCPU(cpu_to_lock); + // To avoid having to link against Google benchmarks in libutil, + // benchmarks are kept without parameter information, necessitating this cast. + reinterpret_cast<void(*) (benchmark::State&)>(func_to_bench)(state); +} + +args_vector_t* ResolveArgs(args_vector_t* to_populate, std::string args, + std::map<std::string, args_vector_t>& args_shorthand) { + // args is either a space-separated list of ints or a macro name. + // To ease formatting in XML files, args is left and right trimmed. + if (args_shorthand.count(args)) { + return &args_shorthand[args]; + } + to_populate->push_back(std::vector<int>()); + std::stringstream sstream(args); + std::string argstr; + while (sstream >> argstr) { + char* check_null; + int converted = static_cast<int>(strtol(argstr.c_str(), &check_null, 10)); + if (*check_null) { + printf("ERROR: Args str %s contains an invalid macro or int.\n", args.c_str()); + abort(); + } + (*to_populate)[0].push_back(converted); + } + return to_populate; +} + +void RegisterGoogleBenchmarks(bench_opts_t primary_opts, bench_opts_t secondary_opts, + std::string fn_name, args_vector_t* run_args) { + if (g_str_to_func.find(fn_name) == g_str_to_func.end()) { + printf("ERROR:No benchmark for function %s\n", fn_name.c_str()); + abort(); + } + long iterations_to_use = primary_opts.num_iterations ? primary_opts.num_iterations : + secondary_opts.num_iterations; + int cpu_to_use = INT_MAX; + if (primary_opts.cpu_to_lock != INT_MAX) { + cpu_to_use = primary_opts.cpu_to_lock; + + } else if (secondary_opts.cpu_to_lock != INT_MAX) { + cpu_to_use = secondary_opts.cpu_to_lock; + } + + for (std::vector<int> args : (*run_args)) { + auto registration = benchmark::RegisterBenchmark(fn_name.c_str(), LockAndRun, + g_str_to_func.at(fn_name), + cpu_to_use)->Args(args); + if (iterations_to_use > 0) { + registration->Iterations(iterations_to_use); + } + } +} + +void RegisterCliBenchmarks(bench_opts_t cmdline_opts, + std::map<std::string, args_vector_t>& args_shorthand) { + // Register any of the extra benchmarks that were specified in the options. + args_vector_t arg_vector; + args_vector_t* run_args = &arg_vector; + for (std::string extra_fn : cmdline_opts.extra_benchmarks) { + android::base::Trim(extra_fn); + size_t first_space_pos = extra_fn.find(" "); + std::string fn_name = extra_fn.substr(0, first_space_pos); + std::string cmd_args; + if (first_space_pos != std::string::npos) { + cmd_args = extra_fn.substr(extra_fn.find(" ") + 1); + } else { + cmd_args = ""; + } + run_args = ResolveArgs(run_args, cmd_args, args_shorthand); + RegisterGoogleBenchmarks(bench_opts_t(), cmdline_opts, fn_name, run_args); + + run_args = &arg_vector; + arg_vector.clear(); + } +} + +int RegisterXmlBenchmarks(bench_opts_t cmdline_opts, + std::map<std::string, args_vector_t>& args_shorthand) { + // Structure of the XML file: + // - Element "fn" Function to benchmark. + // - - Element "iterations" Number of iterations to run. Leaving this blank uses + // Google benchmarks' convergence heuristics. + // - - Element "cpu" CPU to isolate to, if any. + // - - Element "args" Whitespace-separated list of per-function integer arguments, or + // one of the macros defined in util.h. + tinyxml2::XMLDocument doc; + if (doc.LoadFile(cmdline_opts.xmlpath.c_str()) != tinyxml2::XML_NO_ERROR) { + doc.PrintError(); + return doc.ErrorID(); + } + + // Read and register the functions. + tinyxml2::XMLNode* fn = doc.FirstChildElement("fn"); + args_vector_t arg_vector; + args_vector_t* run_args = &arg_vector; + while (fn) { + auto fn_elem = fn->FirstChildElement("name"); + if (!fn_elem) { + printf("Error: Malformed XML entry: missing name element.\n"); + abort(); + } + std::string fn_name = fn_elem->GetText(); + if (fn_name.empty()) { + printf("Error: Malformed XML entry: error parsing name text."); + abort(); + } + auto* xml_args = fn->FirstChildElement("args"); + run_args = ResolveArgs(run_args, xml_args ? android::base::Trim(xml_args->GetText()) : "", + args_shorthand); + + // XML values for CPU and iterations take precedence over those passed in via CLI. + bench_opts_t xml_opts{}; + auto* num_iterations_elem = fn->FirstChildElement("iterations"); + if (num_iterations_elem) { + int temp; + num_iterations_elem->QueryIntText(&temp); + xml_opts.num_iterations = temp; + } else { + xml_opts.num_iterations = 0; + } + auto* cpu_to_lock_elem = fn->FirstChildElement("cpu"); + if (cpu_to_lock_elem) { + int temp; + cpu_to_lock_elem->QueryIntText(&temp); + xml_opts.cpu_to_lock = temp; + } else { + xml_opts.cpu_to_lock = INT_MAX; + } + + RegisterGoogleBenchmarks(xml_opts, cmdline_opts, fn_name, run_args); + + fn = fn->NextSibling(); + run_args = &arg_vector; + arg_vector.clear(); + } + return 0; +} + +std::map<std::string, args_vector_t> GetShorthand() { + std::map<std::string, args_vector_t> args_shorthand { + {"AT_ALIGNED_TWOBUF", args_vector_t{ {8, 0, 0}, + {64, 0, 0}, + {512, 0, 0}, + {1 * KB, 0, 0}, + {8 * KB, 0, 0}, + {16 * KB, 0, 0}, + {32 * KB, 0, 0}, + {64 * KB, 0, 0} }}, + {"AT_ALIGNED_ONEBUF", args_vector_t{ {(8), 0}, + {(64), 0}, + {(512), 0}, + {(1*KB), 0}, + {(8*KB), 0}, + {(16*KB), 0}, + {(32*KB), 0}, + {(64*KB), 0}}}, + + {"AT_COMMON_SIZES", args_vector_t{ {8}, {64}, {512}, {1*KB}, {8*KB}, {16*KB}, + {32*KB}, {64*KB}}}, + + // Do not exceed 512. that is about the largest number of properties + // that can be created with the current property area size. + {"NUM_PROPS", args_vector_t{ {1}, {4}, {16}, {64}, {128}, {256}, {512} }}, + + {"MATH_COMMON", args_vector_t{ {0}, {1}, {2}, {3} }} + }; + for (int i = 1; i < 15; i++) { + int align = pow(2, i); + std::stringstream sstream; + sstream << "AT_" << align << "_ALIGN_TWOBUF"; + args_shorthand.emplace(sstream.str(), + args_vector_t{ {8, align, align}, + {64, align, align}, + {512, align, align}, + {1 * KB, align, align}, + {8 * KB, align, align}, + {16 * KB, align, align}, + {32 * KB, align, align}, + {64 * KB, align, align} }); + sstream.str(""); + sstream << "AT_" << align << "_ALIGN_ONEBUF"; + args_shorthand.emplace(sstream.str(), + args_vector_t{ {(8), align}, + {(64), align}, + {(512), align}, + {(1*KB), align}, + {(8*KB), align}, + {(16*KB), align}, + {(32*KB), align}, + {(64*KB), align} }); + sstream.str(""); + } + return args_shorthand; +} + + +int main(int argc, char** argv) { + std::map<std::string, args_vector_t> args_shorthand = GetShorthand(); + bench_opts_t opts = ParseOpts(argc, argv); + std::vector<char*> new_argv(argc); + SanitizeOpts(argc, argv, &new_argv); + + if (!opts.xmlpath.empty()) { + if (int err = RegisterXmlBenchmarks(opts, args_shorthand)) { + return err; + } + } + RegisterCliBenchmarks(opts, args_shorthand); + + // Set the thread priority to the maximum. + if (setpriority(PRIO_PROCESS, 0, -20)) { + perror("Failed to raise priority of process. Are you root?\n"); + } + + int new_argc = new_argv.size(); + benchmark::Initialize(&new_argc, new_argv.data()); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp index a411c9ca1..7b9a28321 100644 --- a/benchmarks/math_benchmark.cpp +++ b/benchmarks/math_benchmark.cpp @@ -18,11 +18,11 @@ #include <math.h> #include <benchmark/benchmark.h> +#include "util.h" static const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 }; static const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" }; -#define BENCHMARK_COMMON_VALS(name) BENCHMARK(name)->Arg(0)->Arg(1)->Arg(2)->Arg(3) static void SetLabel(benchmark::State& state) { state.SetLabel(names[state.range(0)]); @@ -39,7 +39,7 @@ static void BM_math_sqrt(benchmark::State& state) { d += sqrt(v); } } -BENCHMARK(BM_math_sqrt); +BIONIC_BENCHMARK(BM_math_sqrt); static void BM_math_log10(benchmark::State& state) { d = 0.0; @@ -48,7 +48,7 @@ static void BM_math_log10(benchmark::State& state) { d += log10(v); } } -BENCHMARK(BM_math_log10); +BIONIC_BENCHMARK(BM_math_log10); static void BM_math_logb(benchmark::State& state) { d = 0.0; @@ -57,7 +57,7 @@ static void BM_math_logb(benchmark::State& state) { d += logb(v); } } -BENCHMARK(BM_math_logb); +BIONIC_BENCHMARK(BM_math_logb); static void BM_math_isfinite_macro(benchmark::State& state) { d = 0.0; @@ -67,7 +67,7 @@ static void BM_math_isfinite_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isfinite_macro); +BIONIC_BENCHMARK(BM_math_isfinite_macro); #if defined(__BIONIC__) #define test_isfinite __isfinite @@ -82,7 +82,7 @@ static void BM_math_isfinite(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isfinite); +BIONIC_BENCHMARK(BM_math_isfinite); static void BM_math_isinf_macro(benchmark::State& state) { d = 0.0; @@ -92,7 +92,7 @@ static void BM_math_isinf_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isinf_macro); +BIONIC_BENCHMARK(BM_math_isinf_macro); static void BM_math_isinf(benchmark::State& state) { d = 0.0; @@ -102,7 +102,7 @@ static void BM_math_isinf(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isinf); +BIONIC_BENCHMARK(BM_math_isinf); static void BM_math_isnan_macro(benchmark::State& state) { d = 0.0; @@ -112,7 +112,7 @@ static void BM_math_isnan_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isnan_macro); +BIONIC_BENCHMARK(BM_math_isnan_macro); static void BM_math_isnan(benchmark::State& state) { d = 0.0; @@ -122,7 +122,7 @@ static void BM_math_isnan(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isnan); +BIONIC_BENCHMARK(BM_math_isnan); static void BM_math_isnormal_macro(benchmark::State& state) { d = 0.0; @@ -132,7 +132,7 @@ static void BM_math_isnormal_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isnormal_macro); +BIONIC_BENCHMARK(BM_math_isnormal_macro); #if defined(__BIONIC__) static void BM_math_isnormal(benchmark::State& state) { @@ -143,7 +143,7 @@ static void BM_math_isnormal(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_isnormal); +BIONIC_BENCHMARK(BM_math_isnormal); #endif static void BM_math_sin_fast(benchmark::State& state) { @@ -152,7 +152,7 @@ static void BM_math_sin_fast(benchmark::State& state) { d += sin(d); } } -BENCHMARK(BM_math_sin_fast); +BIONIC_BENCHMARK(BM_math_sin_fast); static void BM_math_sin_feupdateenv(benchmark::State& state) { d = 1.0; @@ -164,7 +164,7 @@ static void BM_math_sin_feupdateenv(benchmark::State& state) { feupdateenv(&__libc_save_rm); } } -BENCHMARK(BM_math_sin_feupdateenv); +BIONIC_BENCHMARK(BM_math_sin_feupdateenv); static void BM_math_sin_fesetenv(benchmark::State& state) { d = 1.0; @@ -176,7 +176,7 @@ static void BM_math_sin_fesetenv(benchmark::State& state) { fesetenv(&__libc_save_rm); } } -BENCHMARK(BM_math_sin_fesetenv); +BIONIC_BENCHMARK(BM_math_sin_fesetenv); static void BM_math_fpclassify(benchmark::State& state) { d = 0.0; @@ -186,7 +186,7 @@ static void BM_math_fpclassify(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_fpclassify); +BIONIC_BENCHMARK(BM_math_fpclassify); static void BM_math_signbit_macro(benchmark::State& state) { d = 0.0; @@ -196,7 +196,7 @@ static void BM_math_signbit_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_signbit_macro); +BIONIC_BENCHMARK(BM_math_signbit_macro); static void BM_math_signbit(benchmark::State& state) { d = 0.0; @@ -206,7 +206,7 @@ static void BM_math_signbit(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_signbit); +BIONIC_BENCHMARK(BM_math_signbit); static void BM_math_fabs_macro(benchmark::State& state) { d = 0.0; @@ -216,7 +216,7 @@ static void BM_math_fabs_macro(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_fabs_macro); +BIONIC_BENCHMARK(BM_math_fabs_macro); static void BM_math_fabs(benchmark::State& state) { d = 0.0; @@ -226,4 +226,4 @@ static void BM_math_fabs(benchmark::State& state) { } SetLabel(state); } -BENCHMARK_COMMON_VALS(BM_math_fabs); +BIONIC_BENCHMARK(BM_math_fabs); diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp index 97eb832c6..a099494b6 100644 --- a/benchmarks/property_benchmark.cpp +++ b/benchmarks/property_benchmark.cpp @@ -27,11 +27,7 @@ #include <sys/_system_properties.h> #include <benchmark/benchmark.h> - -// Do not exceed 512, that is about the largest number of properties -// that can be created with the current property area size. -#define TEST_NUM_PROPS \ - Arg(1)->Arg(4)->Arg(16)->Arg(64)->Arg(128)->Arg(256)->Arg(512) +#include "util.h" struct LocalPropertyTestState { explicit LocalPropertyTestState(int nprops) : nprops(nprops), valid(false) { @@ -145,7 +141,7 @@ static void BM_property_get(benchmark::State& state) { __system_property_get(pa.names[random() % nprops], value); } } -BENCHMARK(BM_property_get)->TEST_NUM_PROPS; +BIONIC_BENCHMARK(BM_property_get); static void BM_property_find(benchmark::State& state) { const size_t nprops = state.range(0); @@ -157,7 +153,7 @@ static void BM_property_find(benchmark::State& state) { __system_property_find(pa.names[random() % nprops]); } } -BENCHMARK(BM_property_find)->TEST_NUM_PROPS; +BIONIC_BENCHMARK(BM_property_find); static void BM_property_read(benchmark::State& state) { const size_t nprops = state.range(0); @@ -180,7 +176,7 @@ static void BM_property_read(benchmark::State& state) { delete[] pinfo; } -BENCHMARK(BM_property_read)->TEST_NUM_PROPS; +BIONIC_BENCHMARK(BM_property_read); static void BM_property_serial(benchmark::State& state) { const size_t nprops = state.range(0); @@ -201,6 +197,6 @@ static void BM_property_serial(benchmark::State& state) { delete[] pinfo; } -BENCHMARK(BM_property_serial)->TEST_NUM_PROPS; +BIONIC_BENCHMARK(BM_property_serial); #endif // __BIONIC__ diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp index d3c2de865..7a967ef73 100644 --- a/benchmarks/pthread_benchmark.cpp +++ b/benchmarks/pthread_benchmark.cpp @@ -17,6 +17,7 @@ #include <pthread.h> #include <benchmark/benchmark.h> +#include "util.h" // Stop GCC optimizing out our pure function. /* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self; @@ -26,7 +27,7 @@ static void BM_pthread_self(benchmark::State& state) { pthread_self_fp(); } } -BENCHMARK(BM_pthread_self); +BIONIC_BENCHMARK(BM_pthread_self); static void BM_pthread_getspecific(benchmark::State& state) { pthread_key_t key; @@ -38,7 +39,7 @@ static void BM_pthread_getspecific(benchmark::State& state) { pthread_key_delete(key); } -BENCHMARK(BM_pthread_getspecific); +BIONIC_BENCHMARK(BM_pthread_getspecific); static void BM_pthread_setspecific(benchmark::State& state) { pthread_key_t key; @@ -50,7 +51,7 @@ static void BM_pthread_setspecific(benchmark::State& state) { pthread_key_delete(key); } -BENCHMARK(BM_pthread_setspecific); +BIONIC_BENCHMARK(BM_pthread_setspecific); static void DummyPthreadOnceInitFunction() { } @@ -63,7 +64,7 @@ static void BM_pthread_once(benchmark::State& state) { pthread_once(&once, DummyPthreadOnceInitFunction); } } -BENCHMARK(BM_pthread_once); +BIONIC_BENCHMARK(BM_pthread_once); static void BM_pthread_mutex_lock(benchmark::State& state) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -73,7 +74,7 @@ static void BM_pthread_mutex_lock(benchmark::State& state) { pthread_mutex_unlock(&mutex); } } -BENCHMARK(BM_pthread_mutex_lock); +BIONIC_BENCHMARK(BM_pthread_mutex_lock); static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) { pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; @@ -83,7 +84,7 @@ static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) { pthread_mutex_unlock(&mutex); } } -BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK); +BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK); static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) { pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; @@ -93,7 +94,7 @@ static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) { pthread_mutex_unlock(&mutex); } } -BENCHMARK(BM_pthread_mutex_lock_RECURSIVE); +BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE); static void BM_pthread_rwlock_read(benchmark::State& state) { pthread_rwlock_t lock; @@ -106,7 +107,7 @@ static void BM_pthread_rwlock_read(benchmark::State& state) { pthread_rwlock_destroy(&lock); } -BENCHMARK(BM_pthread_rwlock_read); +BIONIC_BENCHMARK(BM_pthread_rwlock_read); static void BM_pthread_rwlock_write(benchmark::State& state) { pthread_rwlock_t lock; @@ -119,7 +120,7 @@ static void BM_pthread_rwlock_write(benchmark::State& state) { pthread_rwlock_destroy(&lock); } -BENCHMARK(BM_pthread_rwlock_write); +BIONIC_BENCHMARK(BM_pthread_rwlock_write); static void* IdleThread(void*) { return NULL; @@ -134,7 +135,7 @@ static void BM_pthread_create(benchmark::State& state) { state.ResumeTiming(); } } -BENCHMARK(BM_pthread_create); +BIONIC_BENCHMARK(BM_pthread_create); static void* RunThread(void* arg) { benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); @@ -150,7 +151,7 @@ static void BM_pthread_create_and_run(benchmark::State& state) { state.ResumeTiming(); } } -BENCHMARK(BM_pthread_create_and_run); +BIONIC_BENCHMARK(BM_pthread_create_and_run); static void* ExitThread(void* arg) { benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg); @@ -166,7 +167,7 @@ static void BM_pthread_exit_and_join(benchmark::State& state) { pthread_join(thread, NULL); } } -BENCHMARK(BM_pthread_exit_and_join); +BIONIC_BENCHMARK(BM_pthread_exit_and_join); static void BM_pthread_key_create(benchmark::State& state) { while (state.KeepRunning()) { @@ -178,7 +179,7 @@ static void BM_pthread_key_create(benchmark::State& state) { state.ResumeTiming(); } } -BENCHMARK(BM_pthread_key_create); +BIONIC_BENCHMARK(BM_pthread_key_create); static void BM_pthread_key_delete(benchmark::State& state) { while (state.KeepRunning()) { @@ -190,4 +191,4 @@ static void BM_pthread_key_delete(benchmark::State& state) { pthread_key_delete(key); } } -BENCHMARK(BM_pthread_key_delete); +BIONIC_BENCHMARK(BM_pthread_key_delete); diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp index b932a2b32..a4aa7bb8f 100644 --- a/benchmarks/semaphore_benchmark.cpp +++ b/benchmarks/semaphore_benchmark.cpp @@ -21,6 +21,7 @@ #include <stdlib.h> #include <benchmark/benchmark.h> +#include "util.h" static void BM_semaphore_sem_getvalue(benchmark::State& state) { sem_t semaphore; @@ -31,7 +32,7 @@ static void BM_semaphore_sem_getvalue(benchmark::State& state) { sem_getvalue(&semaphore, &dummy); } } -BENCHMARK(BM_semaphore_sem_getvalue); +BIONIC_BENCHMARK(BM_semaphore_sem_getvalue); static void BM_semaphore_sem_wait_sem_post(benchmark::State& state) { sem_t semaphore; @@ -42,7 +43,7 @@ static void BM_semaphore_sem_wait_sem_post(benchmark::State& state) { sem_post(&semaphore); } } -BENCHMARK(BM_semaphore_sem_wait_sem_post); +BIONIC_BENCHMARK(BM_semaphore_sem_wait_sem_post); // This test reports the overhead of the underlying futex wake syscall on // the producer. It does not report the overhead from issuing the wake to the @@ -119,7 +120,9 @@ class SemaphoreFixture : public benchmark::Fixture { bool setup = false; }; -BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) { +// This is commented out because dynamic benchmark registering doesn't currently support fixtures. +// Uncomment it and recompile to run this benchmark on every run. +/* BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); @@ -149,4 +152,4 @@ BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) { param.sched_priority = 0; sched_setscheduler(0, SCHED_IDLE, ¶m); } -} +}*/ diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp index f49677956..756a698bb 100644 --- a/benchmarks/stdio_benchmark.cpp +++ b/benchmarks/stdio_benchmark.cpp @@ -19,12 +19,7 @@ #include <stdlib.h> #include <benchmark/benchmark.h> - -constexpr auto KB = 1024; - -#define AT_COMMON_SIZES \ - Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(64)->Arg(512)-> \ - Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB) +#include "util.h" template <typename Fn> void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) { @@ -50,22 +45,22 @@ void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) { void BM_stdio_fread(benchmark::State& state) { ReadWriteTest(state, fread, true); } -BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES; +BIONIC_BENCHMARK(BM_stdio_fread); void BM_stdio_fwrite(benchmark::State& state) { ReadWriteTest(state, fwrite, true); } -BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES; +BIONIC_BENCHMARK(BM_stdio_fwrite); void BM_stdio_fread_unbuffered(benchmark::State& state) { ReadWriteTest(state, fread, false); } -BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES; +BIONIC_BENCHMARK(BM_stdio_fread_unbuffered); void BM_stdio_fwrite_unbuffered(benchmark::State& state) { ReadWriteTest(state, fwrite, false); } -BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES; +BIONIC_BENCHMARK(BM_stdio_fwrite_unbuffered); static void FopenFgetsFclose(benchmark::State& state, bool no_locking) { char buf[1024]; @@ -80,9 +75,9 @@ static void FopenFgetsFclose(benchmark::State& state, bool no_locking) { static void BM_stdio_fopen_fgets_fclose_locking(benchmark::State& state) { FopenFgetsFclose(state, false); } -BENCHMARK(BM_stdio_fopen_fgets_fclose_locking); +BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_locking); void BM_stdio_fopen_fgets_fclose_no_locking(benchmark::State& state) { FopenFgetsFclose(state, true); } -BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking); +BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking); diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp index 2ab65a891..729b20dbd 100644 --- a/benchmarks/string_benchmark.cpp +++ b/benchmarks/string_benchmark.cpp @@ -18,27 +18,7 @@ #include <string.h> #include <benchmark/benchmark.h> -#include "util.h" - -constexpr auto KB = 1024; - -// NOTE: these constants are temporary replacements for AT_COMMON_SIZES until -// the new interface for Bionic benchmarks is implemented. - -// Set all four to 0 to test normal alignment. -#define AT_SRC_ALIGN 0 -#define AT_DST_ALIGN 0 - -#define AT_ALIGNED_TWOBUF \ - Args({(8), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64), AT_SRC_ALIGN, AT_DST_ALIGN})-> \ - Args({(512), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(1*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \ - Args({(8*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(16*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \ - Args({(32*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64*KB), AT_SRC_ALIGN, AT_DST_ALIGN}) - -#define AT_ALIGNED_ONEBUF \ - Args({(8), AT_SRC_ALIGN})->Args({(64), AT_SRC_ALIGN})->Args({(512), AT_SRC_ALIGN})-> \ - Args({(1*KB), AT_SRC_ALIGN})->Args({(8*KB), AT_SRC_ALIGN})->Args({(16*KB), AT_SRC_ALIGN})-> \ - Args({(32*KB), AT_SRC_ALIGN})->Args({(64*KB), AT_SRC_ALIGN}) +#include <util.h> static void BM_string_memcmp(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -57,7 +37,7 @@ static void BM_string_memcmp(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memcmp)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_memcmp); static void BM_string_memcpy(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -75,7 +55,7 @@ static void BM_string_memcpy(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memcpy)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_memcpy); static void BM_string_memmove_non_overlapping(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -93,7 +73,7 @@ static void BM_string_memmove_non_overlapping(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memmove_non_overlapping)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_memmove_non_overlapping); static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -108,7 +88,7 @@ static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_ALIGNED_ONEBUF; +BIONIC_BENCHMARK(BM_string_memmove_overlap_dst_before_src); static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -123,7 +103,7 @@ static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_ALIGNED_ONEBUF; +BIONIC_BENCHMARK(BM_string_memmove_overlap_src_before_dst); static void BM_string_memset(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -138,7 +118,7 @@ static void BM_string_memset(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_memset)->AT_ALIGNED_ONEBUF; +BIONIC_BENCHMARK(BM_string_memset); static void BM_string_strlen(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -155,7 +135,7 @@ static void BM_string_strlen(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strlen)->AT_ALIGNED_ONEBUF; +BIONIC_BENCHMARK(BM_string_strlen); static void BM_string_strcat_copy_only(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -178,7 +158,7 @@ static void BM_string_strcat_copy_only(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strcat_copy_only)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_strcat_copy_only); static void BM_string_strcat_seek_only(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -199,7 +179,7 @@ static void BM_string_strcat_seek_only(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strcat_seek_only)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_strcat_seek_only); static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -220,7 +200,7 @@ static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_strcat_half_copy_half_seek); static void BM_string_strcpy(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -239,7 +219,7 @@ static void BM_string_strcpy(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strcpy)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_strcpy); static void BM_string_strcmp(benchmark::State& state) { const size_t nbytes = state.range(0); @@ -260,4 +240,4 @@ static void BM_string_strcmp(benchmark::State& state) { state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes)); } -BENCHMARK(BM_string_strcmp)->AT_ALIGNED_TWOBUF; +BIONIC_BENCHMARK(BM_string_strcmp); diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml new file mode 100644 index 000000000..707a3d626 --- /dev/null +++ b/benchmarks/suites/full.xml @@ -0,0 +1,267 @@ +<fn> + <name>BM_empty</name> +</fn> +<fn> + <name>BM_load_relaxed</name> +</fn> +<fn> + <name>BM_load_acquire</name> +</fn> +<fn> + <name>BM_store_release</name> +</fn> +<fn> + <name>BM_store_seq_cst</name> +</fn> +<fn> + <name>BM_fetch_add_relaxed</name> +</fn> +<fn> + <name>BM_fetch_add_seq_cst</name> +</fn> +<fn> + <name>BM_acquire_fence</name> +</fn> +<fn> + <name>BM_seq_cst_fence</name> +</fn> +<fn> + <name>BM_fetch_add_cs</name> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_math_log10</name> +</fn> +<fn> + <name>BM_math_logb</name> +</fn> +<fn> + <name>BM_math_isfinite_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isfinite</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isinf_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isinf</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isnan_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isnan</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isnormal_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_isnormal</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_sin_fast</name> +</fn> +<fn> + <name>BM_math_sin_feupdateenv</name> +</fn> +<fn> + <name>BM_math_sin_fesetenv</name> +</fn> +<fn> + <name>BM_math_fpclassify</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_signbit_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_signbit</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_fabs_macro</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_math_fabs</name> + <args>MATH_COMMON</args> +</fn> +<fn> + <name>BM_property_get</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_find</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_read</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_serial</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_pthread_self</name> +</fn> +<fn> + <name>BM_pthread_getspecific</name> +</fn> +<fn> + <name>BM_pthread_setspecific</name> +</fn> +<fn> + <name>BM_pthread_once</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_ERRORCHECK</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_RECURSIVE</name> +</fn> +<fn> + <name>BM_pthread_rwlock_read</name> +</fn> +<fn> + <name>BM_pthread_rwlock_write</name> +</fn> +<fn> + <name>BM_pthread_create</name> +</fn> +<fn> + <name>BM_pthread_create_and_run</name> +</fn> +<fn> + <name>BM_pthread_exit_and_join</name> +</fn> +<fn> + <name>BM_pthread_key_create</name> +</fn> +<fn> + <name>BM_pthread_key_delete</name> +</fn> +<fn> + <name>BM_semaphore_sem_getvalue</name> +</fn> +<fn> + <name>BM_semaphore_sem_wait_sem_post</name> +</fn> +<fn> + <name>BM_stdio_fread</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fread_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_locking</name> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_no_locking</name> +</fn> +<fn> + <name>BM_string_memcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memmove_non_overlapping</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_dst_before_src</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_src_before_dst</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memset</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strcat_copy_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_seek_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_half_copy_half_seek</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_time_clock_gettime</name> +</fn> +<fn> + <name>BM_time_clock_gettime_syscall</name> +</fn> +<fn> + <name>BM_time_gettimeofday</name> +</fn> +<fn> + <name>BM_time_gettimeofday_syscall</name> +</fn> +<fn> + <name>BM_time_time</name> +</fn> +<fn> + <name>BM_time_localtime</name> +</fn> +<fn> + <name>BM_time_localtime_r</name> +</fn> +<fn> + <name>BM_unistd_getpid</name> +</fn> +<fn> + <name>BM_unistd_getpid_syscall</name> +</fn> +<fn> + <name>BM_unistd_gettid</name> +</fn> +<fn> + <name>BM_unistd_gettid_syscall</name> +</fn> diff --git a/benchmarks/suites/host.xml b/benchmarks/suites/host.xml new file mode 100644 index 000000000..c4d0d3a3e --- /dev/null +++ b/benchmarks/suites/host.xml @@ -0,0 +1,244 @@ +<fn> + <name>BM_empty</name> +</fn> +<fn> + <name>BM_load_relaxed</name> +</fn> +<fn> + <name>BM_load_acquire</name> +</fn> +<fn> + <name>BM_store_release</name> +</fn> +<fn> + <name>BM_store_seq_cst</name> +</fn> +<fn> + <name>BM_fetch_add_relaxed</name> +</fn> +<fn> + <name>BM_fetch_add_seq_cst</name> +</fn> +<fn> + <name>BM_acquire_fence</name> +</fn> +<fn> + <name>BM_seq_cst_fence</name> +</fn> +<fn> + <name>BM_fetch_add_cs</name> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_math_log10</name> +</fn> +<fn> + <name>BM_math_logb</name> +</fn> +<fn> + <name>BM_math_isfinite_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isfinite</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isinf_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isinf</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnan_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnan</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnormal_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_sin_fast</name> +</fn> +<fn> + <name>BM_math_sin_feupdateenv</name> +</fn> +<fn> + <name>BM_math_sin_fesetenv</name> +</fn> +<fn> + <name>BM_math_fpclassify</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_signbit_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_signbit</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_fabs_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_fabs</name> + <args>0</args> +</fn> +<fn> + <name>BM_pthread_self</name> +</fn> +<fn> + <name>BM_pthread_getspecific</name> +</fn> +<fn> + <name>BM_pthread_setspecific</name> +</fn> +<fn> + <name>BM_pthread_once</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_ERRORCHECK</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_RECURSIVE</name> +</fn> +<fn> + <name>BM_pthread_rwlock_read</name> +</fn> +<fn> + <name>BM_pthread_rwlock_write</name> +</fn> +<fn> + <name>BM_pthread_create</name> +</fn> +<fn> + <name>BM_pthread_create_and_run</name> +</fn> +<fn> + <name>BM_pthread_exit_and_join</name> +</fn> +<fn> + <name>BM_pthread_key_create</name> +</fn> +<fn> + <name>BM_pthread_key_delete</name> +</fn> +<fn> + <name>BM_semaphore_sem_getvalue</name> +</fn> +<fn> + <name>BM_semaphore_sem_wait_sem_post</name> +</fn> +<fn> + <name>BM_stdio_fread</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fread_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_locking</name> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_no_locking</name> +</fn> +<fn> + <name>BM_string_memcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memmove_non_overlapping</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_dst_before_src</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_src_before_dst</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memset</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strcat_copy_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_seek_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_half_copy_half_seek</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_time_clock_gettime</name> +</fn> +<fn> + <name>BM_time_clock_gettime_syscall</name> +</fn> +<fn> + <name>BM_time_gettimeofday</name> +</fn> +<fn> + <name>BM_time_gettimeofday_syscall</name> +</fn> +<fn> + <name>BM_time_time</name> +</fn> +<fn> + <name>BM_time_localtime</name> +</fn> +<fn> + <name>BM_time_localtime_r</name> +</fn> +<fn> + <name>BM_unistd_getpid</name> +</fn> +<fn> + <name>BM_unistd_getpid_syscall</name> +</fn> +<fn> + <name>BM_unistd_gettid_syscall</name> +</fn> diff --git a/benchmarks/suites/test_alignment.xml b/benchmarks/suites/test_alignment.xml new file mode 100644 index 000000000..20df3202d --- /dev/null +++ b/benchmarks/suites/test_alignment.xml @@ -0,0 +1,50 @@ +<fn> + <name>BM_string_memcmp</name> + <iterations>1</iterations> + <args>AT_2_ALIGN_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcmp</name> + <iterations>1</iterations> + <args>AT_4_ALIGN_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcmp</name> + <iterations>1</iterations> + <args>AT_16_ALIGN_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcmp</name> + <iterations>1</iterations> + <args>AT_512_ALIGN_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcmp</name> + <iterations>1</iterations> + <args>AT_2048_ALIGN_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <iterations>1</iterations> + <args>AT_2_ALIGN_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <iterations>1</iterations> + <args>AT_4_ALIGN_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <iterations>1</iterations> + <args>AT_16_ALIGN_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <iterations>1</iterations> + <args>AT_512_ALIGN_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <iterations>1</iterations> + <args>AT_2048_ALIGN_ONEBUF</args> +</fn> diff --git a/benchmarks/suites/test_from_each.xml b/benchmarks/suites/test_from_each.xml new file mode 100644 index 000000000..01183650a --- /dev/null +++ b/benchmarks/suites/test_from_each.xml @@ -0,0 +1,30 @@ +<fn> + <name>BM_empty</name> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_property_get</name> + <args>1</args> +</fn> +<fn> + <name>BM_pthread_self</name> +</fn> +<fn> + <name>BM_semaphore_sem_getvalue</name> +</fn> +<fn> + <name>BM_stdio_fread</name> + <args>64</args> +</fn> +<fn> + <name>BM_string_memcpy</name> + <args>512 4 4</args> +</fn> +<fn> + <name>BM_time_clock_gettime</name> +</fn> +<fn> + <name>BM_unistd_getpid</name> +</fn> diff --git a/benchmarks/suites/test_full.xml b/benchmarks/suites/test_full.xml new file mode 100644 index 000000000..f9d97ee4f --- /dev/null +++ b/benchmarks/suites/test_full.xml @@ -0,0 +1,261 @@ +<fn> + <name>BM_empty</name> +</fn> +<fn> + <name>BM_load_relaxed</name> +</fn> +<fn> + <name>BM_load_acquire</name> +</fn> +<fn> + <name>BM_store_release</name> +</fn> +<fn> + <name>BM_store_seq_cst</name> +</fn> +<fn> + <name>BM_fetch_add_relaxed</name> +</fn> +<fn> + <name>BM_fetch_add_seq_cst</name> +</fn> +<fn> + <name>BM_acquire_fence</name> +</fn> +<fn> + <name>BM_seq_cst_fence</name> +</fn> +<fn> + <name>BM_fetch_add_cs</name> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_math_log10</name> +</fn> +<fn> + <name>BM_math_logb</name> +</fn> +<fn> + <name>BM_math_isfinite_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isfinite</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isinf_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isinf</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnan_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnan</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnormal_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_isnormal</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_sin_fast</name> +</fn> +<fn> + <name>BM_math_sin_feupdateenv</name> +</fn> +<fn> + <name>BM_math_sin_fesetenv</name> +</fn> +<fn> + <name>BM_math_fpclassify</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_signbit_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_signbit</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_fabs_macro</name> + <args>0</args> +</fn> +<fn> + <name>BM_math_fabs</name> + <args>0</args> +</fn> +<fn> + <name>BM_property_get</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_find</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_read</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_property_serial</name> + <args>NUM_PROPS</args> +</fn> +<fn> + <name>BM_pthread_self</name> +</fn> +<fn> + <name>BM_pthread_getspecific</name> +</fn> +<fn> + <name>BM_pthread_setspecific</name> +</fn> +<fn> + <name>BM_pthread_once</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_ERRORCHECK</name> +</fn> +<fn> + <name>BM_pthread_mutex_lock_RECURSIVE</name> +</fn> +<fn> + <name>BM_pthread_rwlock_read</name> +</fn> +<fn> + <name>BM_pthread_rwlock_write</name> +</fn> +<fn> + <name>BM_pthread_create</name> +</fn> +<fn> + <name>BM_pthread_create_and_run</name> +</fn> +<fn> + <name>BM_pthread_exit_and_join</name> +</fn> +<fn> + <name>BM_pthread_key_create</name> +</fn> +<fn> + <name>BM_pthread_key_delete</name> +</fn> +<fn> + <name>BM_semaphore_sem_getvalue</name> +</fn> +<fn> + <name>BM_semaphore_sem_wait_sem_post</name> +</fn> +<fn> + <name>BM_stdio_fread</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fread_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fwrite_unbuffered</name> + <args>AT_COMMON_SIZES</args> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_locking</name> +</fn> +<fn> + <name>BM_stdio_fopen_fgets_fclose_no_locking</name> +</fn> +<fn> + <name>BM_string_memcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_memmove_non_overlapping</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_dst_before_src</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memmove_overlap_src_before_dst</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_memset</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strlen</name> + <args>AT_ALIGNED_ONEBUF</args> +</fn> +<fn> + <name>BM_string_strcat_copy_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_seek_only</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcat_half_copy_half_seek</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcpy</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_string_strcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_time_clock_gettime</name> +</fn> +<fn> + <name>BM_time_clock_gettime_syscall</name> +</fn> +<fn> + <name>BM_time_gettimeofday</name> +</fn> +<fn> + <name>BM_time_gettimeofday_syscall</name> +</fn> +<fn> + <name>BM_time_time</name> +</fn> +<fn> + <name>BM_unistd_getpid</name> +</fn> +<fn> + <name>BM_unistd_getpid_syscall</name> +</fn> +<fn> + <name>BM_unistd_gettid</name> +</fn> +<fn> + <name>BM_unistd_gettid_syscall</name> +</fn> diff --git a/benchmarks/suites/test_medium.xml b/benchmarks/suites/test_medium.xml new file mode 100644 index 000000000..9528af35e --- /dev/null +++ b/benchmarks/suites/test_medium.xml @@ -0,0 +1,16 @@ +<fn> + <name>BM_string_memcmp</name> + <args>AT_ALIGNED_TWOBUF</args> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_string_memcpy</name> + <iterations>25</iterations> + <args>512 4 4</args> +</fn> +<fn> + <name>BM_property_get</name> + <args>1</args> +</fn> diff --git a/benchmarks/suites/test_small.xml b/benchmarks/suites/test_small.xml new file mode 100644 index 000000000..a4cc28527 --- /dev/null +++ b/benchmarks/suites/test_small.xml @@ -0,0 +1,11 @@ +<fn> + <name>BM_string_memcmp</name> + <args>8 8 8</args> +</fn> +<fn> + <name>BM_math_sqrt</name> +</fn> +<fn> + <name>BM_property_get</name> + <args>1</args> +</fn> diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp new file mode 100644 index 000000000..a9e303106 --- /dev/null +++ b/benchmarks/tests/interface_test.cpp @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <regex> +#include <string> +#include <vector> + +#include <gtest/gtest.h> + +class SystemTests : public ::testing::Test { + protected: + void SetUp() override { + raw_output_ = ""; + sanitized_output_ = ""; + exitcode_ = 0; + } + + void SanitizeOutput(); + + void Exec(std::vector<const char*> args); + void ExecAndCapture(std::vector<const char*> args); + void RunTest(std::vector<const char*> extra_args = {}); + void Verify(const std::string& expected_output, int expected_exitcode, + std::vector<const char*> extra_args = {}); + + std::string raw_output_; + std::string sanitized_output_; + int exitcode_; + pid_t pid_; + int fd_; +}; + +void SystemTests::SanitizeOutput() { + // Cut off anything after the arguments, since that varies with time. + sanitized_output_ = std::regex_replace(raw_output_, std::regex(".+(BM_\\S+) +.+"), "$1"); + + // Remove everything before the header. + sanitized_output_.erase(0, sanitized_output_.find("------------------------------------------------")); + + // Remove the header. + sanitized_output_.erase(0, sanitized_output_.find("BM_")); + + // Remove any hanging output. + sanitized_output_.erase(sanitized_output_.find_last_of("BM_\\S+\n") + 1); +} + +static void GetExe(std::string* exe_name) { + char path[PATH_MAX]; + ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path)); + ASSERT_TRUE(path_len >= 0); + *exe_name = std::string(std::regex_replace(path, std::regex("-tests"), "")); +} + +void SystemTests::Exec(std::vector<const char*> args) { + int fds[2]; + ASSERT_NE(-1, pipe(fds)); + ASSERT_NE(-1, fcntl(fds[0], F_SETFL, O_NONBLOCK)); + + if ((pid_ = fork()) == 0) { + // Run the test. + close(fds[0]); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + ASSERT_NE(0, dup2(fds[1], STDOUT_FILENO)); + ASSERT_NE(0, dup2(fds[1], STDERR_FILENO)); + close(fds[1]); + + std::string exe_name; + GetExe(&exe_name); + args.insert(args.begin(), exe_name.c_str()); + args.push_back(nullptr); + execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data()))); + exit(1); + } + ASSERT_NE(-1, pid_); + + close(fds[1]); + fd_ = fds[0]; +} + +void SystemTests::Verify(const std::string& expected_output, + int expected_exitcode, std::vector<const char*> extra_args) { + std::vector<const char*> args; + for (const auto& arg : extra_args) { + args.push_back(arg); + } + + Exec(args); + + raw_output_ = ""; + while (true) { + char buffer[4097]; + ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer, sizeof(buffer) - 1)); + if (bytes == -1 && errno == EAGAIN) { + continue; + } + ASSERT_NE(-1, bytes); + if (bytes == 0) { + break; + } + buffer[bytes] = '\0'; + raw_output_ += buffer; + } + close(fd_); + + int status; + ASSERT_EQ(pid_, TEMP_FAILURE_RETRY(waitpid(pid_, &status, 0))) << "Test output:\n" << raw_output_; + exitcode_ = WEXITSTATUS(status); + SanitizeOutput(); + + ASSERT_EQ(expected_exitcode, exitcode_) << "Test output:\n" << raw_output_; + if (!expected_output.empty()) { + ASSERT_EQ(expected_output, sanitized_output_); + } + +} + +TEST_F(SystemTests, full_suite) { + std::string expected = + "BM_empty/iterations:1\n" + "BM_load_relaxed/iterations:1\n" + "BM_load_acquire/iterations:1\n" + "BM_store_release/iterations:1\n" + "BM_store_seq_cst/iterations:1\n" + "BM_fetch_add_relaxed/iterations:1\n" + "BM_fetch_add_seq_cst/iterations:1\n" + "BM_acquire_fence/iterations:1\n" + "BM_seq_cst_fence/iterations:1\n" + "BM_fetch_add_cs/iterations:1\n" + "BM_math_sqrt/iterations:1\n" + "BM_math_log10/iterations:1\n" + "BM_math_logb/iterations:1\n" + "BM_math_isfinite_macro/0/iterations:1\n" + "BM_math_isfinite/0/iterations:1\n" + "BM_math_isinf_macro/0/iterations:1\n" + "BM_math_isinf/0/iterations:1\n" + "BM_math_isnan_macro/0/iterations:1\n" + "BM_math_isnan/0/iterations:1\n" + "BM_math_isnormal_macro/0/iterations:1\n" + "BM_math_isnormal/0/iterations:1\n" + "BM_math_sin_fast/iterations:1\n" + "BM_math_sin_feupdateenv/iterations:1\n" + "BM_math_sin_fesetenv/iterations:1\n" + "BM_math_fpclassify/0/iterations:1\n" + "BM_math_signbit_macro/0/iterations:1\n" + "BM_math_signbit/0/iterations:1\n" + "BM_math_fabs_macro/0/iterations:1\n" + "BM_math_fabs/0/iterations:1\n" + "BM_property_get/1/iterations:1\n" + "BM_property_get/4/iterations:1\n" + "BM_property_get/16/iterations:1\n" + "BM_property_get/64/iterations:1\n" + "BM_property_get/128/iterations:1\n" + "BM_property_get/256/iterations:1\n" + "BM_property_get/512/iterations:1\n" + "BM_property_find/1/iterations:1\n" + "BM_property_find/4/iterations:1\n" + "BM_property_find/16/iterations:1\n" + "BM_property_find/64/iterations:1\n" + "BM_property_find/128/iterations:1\n" + "BM_property_find/256/iterations:1\n" + "BM_property_find/512/iterations:1\n" + "BM_property_read/1/iterations:1\n" + "BM_property_read/4/iterations:1\n" + "BM_property_read/16/iterations:1\n" + "BM_property_read/64/iterations:1\n" + "BM_property_read/128/iterations:1\n" + "BM_property_read/256/iterations:1\n" + "BM_property_read/512/iterations:1\n" + "BM_property_serial/1/iterations:1\n" + "BM_property_serial/4/iterations:1\n" + "BM_property_serial/16/iterations:1\n" + "BM_property_serial/64/iterations:1\n" + "BM_property_serial/128/iterations:1\n" + "BM_property_serial/256/iterations:1\n" + "BM_property_serial/512/iterations:1\n" + "BM_pthread_self/iterations:1\n" + "BM_pthread_getspecific/iterations:1\n" + "BM_pthread_setspecific/iterations:1\n" + "BM_pthread_once/iterations:1\n" + "BM_pthread_mutex_lock/iterations:1\n" + "BM_pthread_mutex_lock_ERRORCHECK/iterations:1\n" + "BM_pthread_mutex_lock_RECURSIVE/iterations:1\n" + "BM_pthread_rwlock_read/iterations:1\n" + "BM_pthread_rwlock_write/iterations:1\n" + "BM_pthread_create/iterations:1\n" + "BM_pthread_create_and_run/iterations:1\n" + "BM_pthread_exit_and_join/iterations:1\n" + "BM_pthread_key_create/iterations:1\n" + "BM_pthread_key_delete/iterations:1\n" + "BM_semaphore_sem_getvalue/iterations:1\n" + "BM_semaphore_sem_wait_sem_post/iterations:1\n" + "BM_stdio_fread/8/iterations:1\n" + "BM_stdio_fread/64/iterations:1\n" + "BM_stdio_fread/512/iterations:1\n" + "BM_stdio_fread/1024/iterations:1\n" + "BM_stdio_fread/8192/iterations:1\n" + "BM_stdio_fread/16384/iterations:1\n" + "BM_stdio_fread/32768/iterations:1\n" + "BM_stdio_fread/65536/iterations:1\n" + "BM_stdio_fwrite/8/iterations:1\n" + "BM_stdio_fwrite/64/iterations:1\n" + "BM_stdio_fwrite/512/iterations:1\n" + "BM_stdio_fwrite/1024/iterations:1\n" + "BM_stdio_fwrite/8192/iterations:1\n" + "BM_stdio_fwrite/16384/iterations:1\n" + "BM_stdio_fwrite/32768/iterations:1\n" + "BM_stdio_fwrite/65536/iterations:1\n" + "BM_stdio_fread_unbuffered/8/iterations:1\n" + "BM_stdio_fread_unbuffered/64/iterations:1\n" + "BM_stdio_fread_unbuffered/512/iterations:1\n" + "BM_stdio_fread_unbuffered/1024/iterations:1\n" + "BM_stdio_fread_unbuffered/8192/iterations:1\n" + "BM_stdio_fread_unbuffered/16384/iterations:1\n" + "BM_stdio_fread_unbuffered/32768/iterations:1\n" + "BM_stdio_fread_unbuffered/65536/iterations:1\n" + "BM_stdio_fwrite_unbuffered/8/iterations:1\n" + "BM_stdio_fwrite_unbuffered/64/iterations:1\n" + "BM_stdio_fwrite_unbuffered/512/iterations:1\n" + "BM_stdio_fwrite_unbuffered/1024/iterations:1\n" + "BM_stdio_fwrite_unbuffered/8192/iterations:1\n" + "BM_stdio_fwrite_unbuffered/16384/iterations:1\n" + "BM_stdio_fwrite_unbuffered/32768/iterations:1\n" + "BM_stdio_fwrite_unbuffered/65536/iterations:1\n" + "BM_stdio_fopen_fgets_fclose_locking/iterations:1\n" + "BM_stdio_fopen_fgets_fclose_no_locking/iterations:1\n" + "BM_string_memcmp/8/0/0/iterations:1\n" + "BM_string_memcmp/64/0/0/iterations:1\n" + "BM_string_memcmp/512/0/0/iterations:1\n" + "BM_string_memcmp/1024/0/0/iterations:1\n" + "BM_string_memcmp/8192/0/0/iterations:1\n" + "BM_string_memcmp/16384/0/0/iterations:1\n" + "BM_string_memcmp/32768/0/0/iterations:1\n" + "BM_string_memcmp/65536/0/0/iterations:1\n" + "BM_string_memcpy/8/0/0/iterations:1\n" + "BM_string_memcpy/64/0/0/iterations:1\n" + "BM_string_memcpy/512/0/0/iterations:1\n" + "BM_string_memcpy/1024/0/0/iterations:1\n" + "BM_string_memcpy/8192/0/0/iterations:1\n" + "BM_string_memcpy/16384/0/0/iterations:1\n" + "BM_string_memcpy/32768/0/0/iterations:1\n" + "BM_string_memcpy/65536/0/0/iterations:1\n" + "BM_string_memmove_non_overlapping/8/0/iterations:1\n" + "BM_string_memmove_non_overlapping/64/0/iterations:1\n" + "BM_string_memmove_non_overlapping/512/0/iterations:1\n" + "BM_string_memmove_non_overlapping/1024/0/iterations:1\n" + "BM_string_memmove_non_overlapping/8192/0/iterations:1\n" + "BM_string_memmove_non_overlapping/16384/0/iterations:1\n" + "BM_string_memmove_non_overlapping/32768/0/iterations:1\n" + "BM_string_memmove_non_overlapping/65536/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/8/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/64/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/512/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/1024/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/8192/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/16384/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/32768/0/iterations:1\n" + "BM_string_memmove_overlap_dst_before_src/65536/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/8/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/64/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/512/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/1024/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/8192/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/16384/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/32768/0/iterations:1\n" + "BM_string_memmove_overlap_src_before_dst/65536/0/iterations:1\n" + "BM_string_memset/8/0/iterations:1\n" + "BM_string_memset/64/0/iterations:1\n" + "BM_string_memset/512/0/iterations:1\n" + "BM_string_memset/1024/0/iterations:1\n" + "BM_string_memset/8192/0/iterations:1\n" + "BM_string_memset/16384/0/iterations:1\n" + "BM_string_memset/32768/0/iterations:1\n" + "BM_string_memset/65536/0/iterations:1\n" + "BM_string_strlen/8/0/iterations:1\n" + "BM_string_strlen/64/0/iterations:1\n" + "BM_string_strlen/512/0/iterations:1\n" + "BM_string_strlen/1024/0/iterations:1\n" + "BM_string_strlen/8192/0/iterations:1\n" + "BM_string_strlen/16384/0/iterations:1\n" + "BM_string_strlen/32768/0/iterations:1\n" + "BM_string_strlen/65536/0/iterations:1\n" + "BM_string_strcat_copy_only/8/0/0/iterations:1\n" + "BM_string_strcat_copy_only/64/0/0/iterations:1\n" + "BM_string_strcat_copy_only/512/0/0/iterations:1\n" + "BM_string_strcat_copy_only/1024/0/0/iterations:1\n" + "BM_string_strcat_copy_only/8192/0/0/iterations:1\n" + "BM_string_strcat_copy_only/16384/0/0/iterations:1\n" + "BM_string_strcat_copy_only/32768/0/0/iterations:1\n" + "BM_string_strcat_copy_only/65536/0/0/iterations:1\n" + "BM_string_strcat_seek_only/8/0/0/iterations:1\n" + "BM_string_strcat_seek_only/64/0/0/iterations:1\n" + "BM_string_strcat_seek_only/512/0/0/iterations:1\n" + "BM_string_strcat_seek_only/1024/0/0/iterations:1\n" + "BM_string_strcat_seek_only/8192/0/0/iterations:1\n" + "BM_string_strcat_seek_only/16384/0/0/iterations:1\n" + "BM_string_strcat_seek_only/32768/0/0/iterations:1\n" + "BM_string_strcat_seek_only/65536/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/8/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/64/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/512/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/1024/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/8192/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/16384/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/32768/0/0/iterations:1\n" + "BM_string_strcat_half_copy_half_seek/65536/0/0/iterations:1\n" + "BM_string_strcpy/8/0/0/iterations:1\n" + "BM_string_strcpy/64/0/0/iterations:1\n" + "BM_string_strcpy/512/0/0/iterations:1\n" + "BM_string_strcpy/1024/0/0/iterations:1\n" + "BM_string_strcpy/8192/0/0/iterations:1\n" + "BM_string_strcpy/16384/0/0/iterations:1\n" + "BM_string_strcpy/32768/0/0/iterations:1\n" + "BM_string_strcpy/65536/0/0/iterations:1\n" + "BM_string_strcmp/8/0/0/iterations:1\n" + "BM_string_strcmp/64/0/0/iterations:1\n" + "BM_string_strcmp/512/0/0/iterations:1\n" + "BM_string_strcmp/1024/0/0/iterations:1\n" + "BM_string_strcmp/8192/0/0/iterations:1\n" + "BM_string_strcmp/16384/0/0/iterations:1\n" + "BM_string_strcmp/32768/0/0/iterations:1\n" + "BM_string_strcmp/65536/0/0/iterations:1\n" + "BM_time_clock_gettime/iterations:1\n" + "BM_time_clock_gettime_syscall/iterations:1\n" + "BM_time_gettimeofday/iterations:1\n" + "BM_time_gettimeofday_syscall/iterations:1\n" + "BM_time_time/iterations:1\n" + "BM_unistd_getpid/iterations:1\n" + "BM_unistd_getpid_syscall/iterations:1\n" + "BM_unistd_gettid/iterations:1\n" + "BM_unistd_gettid_syscall/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_full.xml", + "--bionic_iterations=1"}); +} + +TEST_F(SystemTests, small) { + std::string expected = + "BM_string_memcmp/8/8/8\n" + "BM_math_sqrt\n" + "BM_property_get/1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_small.xml"}); +} + +TEST_F(SystemTests, medium) { + std::string expected = + "BM_string_memcmp/8/0/0/iterations:1\n" + "BM_string_memcmp/64/0/0/iterations:1\n" + "BM_string_memcmp/512/0/0/iterations:1\n" + "BM_string_memcmp/1024/0/0/iterations:1\n" + "BM_string_memcmp/8192/0/0/iterations:1\n" + "BM_string_memcmp/16384/0/0/iterations:1\n" + "BM_string_memcmp/32768/0/0/iterations:1\n" + "BM_string_memcmp/65536/0/0/iterations:1\n" + "BM_math_sqrt/iterations:1\n" + "BM_string_memcpy/512/4/4/iterations:25\n" + "BM_property_get/1/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_medium.xml", + "--bionic_iterations=1"}); +} + +TEST_F(SystemTests, from_each) { + std::string expected = + "BM_empty/iterations:1\n" + "BM_math_sqrt/iterations:1\n" + "BM_property_get/1/iterations:1\n" + "BM_pthread_self/iterations:1\n" + "BM_semaphore_sem_getvalue/iterations:1\n" + "BM_stdio_fread/64/iterations:1\n" + "BM_string_memcpy/512/4/4/iterations:1\n" + "BM_time_clock_gettime/iterations:1\n" + "BM_unistd_getpid/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_from_each.xml", + "--bionic_iterations=1"}); +} + +TEST_F(SystemTests, cmd_args) { + std::string expected = + "BM_string_memcpy/8/8/8/iterations:1\n" + "BM_math_log10/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_extra=BM_string_memcpy 8 8 8", + "--bionic_extra=BM_math_log10", + "--bionic_iterations=1"}); +} + +TEST_F(SystemTests, cmd_args_no_iter) { + std::string expected = + "BM_string_memcpy/8/8/8\n" + "BM_math_log10\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_extra=BM_string_memcpy 8 8 8", + "--bionic_extra=BM_math_log10"}); +} + +TEST_F(SystemTests, xml_and_args) { + std::string expected = + "BM_string_memcmp/8/0/0/iterations:1\n" + "BM_string_memcmp/64/0/0/iterations:1\n" + "BM_string_memcmp/512/0/0/iterations:1\n" + "BM_string_memcmp/1024/0/0/iterations:1\n" + "BM_string_memcmp/8192/0/0/iterations:1\n" + "BM_string_memcmp/16384/0/0/iterations:1\n" + "BM_string_memcmp/32768/0/0/iterations:1\n" + "BM_string_memcmp/65536/0/0/iterations:1\n" + "BM_math_sqrt/iterations:1\n" + "BM_string_memcpy/512/4/4/iterations:25\n" + "BM_property_get/1/iterations:1\n" + "BM_string_memcpy/8/0/0/iterations:1\n" + "BM_string_memcpy/64/0/0/iterations:1\n" + "BM_string_memcpy/512/0/0/iterations:1\n" + "BM_string_memcpy/1024/0/0/iterations:1\n" + "BM_string_memcpy/8192/0/0/iterations:1\n" + "BM_string_memcpy/16384/0/0/iterations:1\n" + "BM_string_memcpy/32768/0/0/iterations:1\n" + "BM_string_memcpy/65536/0/0/iterations:1\n" + "BM_math_log10/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_extra=BM_string_memcpy AT_ALIGNED_TWOBUF", + "--bionic_extra=BM_math_log10", + "--bionic_cpu -1", + "--bionic_xml=suites/test_medium.xml", + "--bionic_iterations=1"}); +} + +TEST_F(SystemTests, alignment) { + std::string expected = + "BM_string_memcmp/8/2/2/iterations:1\n" + "BM_string_memcmp/64/2/2/iterations:1\n" + "BM_string_memcmp/512/2/2/iterations:1\n" + "BM_string_memcmp/1024/2/2/iterations:1\n" + "BM_string_memcmp/8192/2/2/iterations:1\n" + "BM_string_memcmp/16384/2/2/iterations:1\n" + "BM_string_memcmp/32768/2/2/iterations:1\n" + "BM_string_memcmp/65536/2/2/iterations:1\n" + "BM_string_memcmp/8/4/4/iterations:1\n" + "BM_string_memcmp/64/4/4/iterations:1\n" + "BM_string_memcmp/512/4/4/iterations:1\n" + "BM_string_memcmp/1024/4/4/iterations:1\n" + "BM_string_memcmp/8192/4/4/iterations:1\n" + "BM_string_memcmp/16384/4/4/iterations:1\n" + "BM_string_memcmp/32768/4/4/iterations:1\n" + "BM_string_memcmp/65536/4/4/iterations:1\n" + "BM_string_memcmp/8/16/16/iterations:1\n" + "BM_string_memcmp/64/16/16/iterations:1\n" + "BM_string_memcmp/512/16/16/iterations:1\n" + "BM_string_memcmp/1024/16/16/iterations:1\n" + "BM_string_memcmp/8192/16/16/iterations:1\n" + "BM_string_memcmp/16384/16/16/iterations:1\n" + "BM_string_memcmp/32768/16/16/iterations:1\n" + "BM_string_memcmp/65536/16/16/iterations:1\n" + "BM_string_memcmp/8/512/512/iterations:1\n" + "BM_string_memcmp/64/512/512/iterations:1\n" + "BM_string_memcmp/512/512/512/iterations:1\n" + "BM_string_memcmp/1024/512/512/iterations:1\n" + "BM_string_memcmp/8192/512/512/iterations:1\n" + "BM_string_memcmp/16384/512/512/iterations:1\n" + "BM_string_memcmp/32768/512/512/iterations:1\n" + "BM_string_memcmp/65536/512/512/iterations:1\n" + "BM_string_memcmp/8/2048/2048/iterations:1\n" + "BM_string_memcmp/64/2048/2048/iterations:1\n" + "BM_string_memcmp/512/2048/2048/iterations:1\n" + "BM_string_memcmp/1024/2048/2048/iterations:1\n" + "BM_string_memcmp/8192/2048/2048/iterations:1\n" + "BM_string_memcmp/16384/2048/2048/iterations:1\n" + "BM_string_memcmp/32768/2048/2048/iterations:1\n" + "BM_string_memcmp/65536/2048/2048/iterations:1\n" + "BM_string_strlen/8/2/iterations:1\n" + "BM_string_strlen/64/2/iterations:1\n" + "BM_string_strlen/512/2/iterations:1\n" + "BM_string_strlen/1024/2/iterations:1\n" + "BM_string_strlen/8192/2/iterations:1\n" + "BM_string_strlen/16384/2/iterations:1\n" + "BM_string_strlen/32768/2/iterations:1\n" + "BM_string_strlen/65536/2/iterations:1\n" + "BM_string_strlen/8/4/iterations:1\n" + "BM_string_strlen/64/4/iterations:1\n" + "BM_string_strlen/512/4/iterations:1\n" + "BM_string_strlen/1024/4/iterations:1\n" + "BM_string_strlen/8192/4/iterations:1\n" + "BM_string_strlen/16384/4/iterations:1\n" + "BM_string_strlen/32768/4/iterations:1\n" + "BM_string_strlen/65536/4/iterations:1\n" + "BM_string_strlen/8/16/iterations:1\n" + "BM_string_strlen/64/16/iterations:1\n" + "BM_string_strlen/512/16/iterations:1\n" + "BM_string_strlen/1024/16/iterations:1\n" + "BM_string_strlen/8192/16/iterations:1\n" + "BM_string_strlen/16384/16/iterations:1\n" + "BM_string_strlen/32768/16/iterations:1\n" + "BM_string_strlen/65536/16/iterations:1\n" + "BM_string_strlen/8/512/iterations:1\n" + "BM_string_strlen/64/512/iterations:1\n" + "BM_string_strlen/512/512/iterations:1\n" + "BM_string_strlen/1024/512/iterations:1\n" + "BM_string_strlen/8192/512/iterations:1\n" + "BM_string_strlen/16384/512/iterations:1\n" + "BM_string_strlen/32768/512/iterations:1\n" + "BM_string_strlen/65536/512/iterations:1\n" + "BM_string_strlen/8/2048/iterations:1\n" + "BM_string_strlen/64/2048/iterations:1\n" + "BM_string_strlen/512/2048/iterations:1\n" + "BM_string_strlen/1024/2048/iterations:1\n" + "BM_string_strlen/8192/2048/iterations:1\n" + "BM_string_strlen/16384/2048/iterations:1\n" + "BM_string_strlen/32768/2048/iterations:1\n" + "BM_string_strlen/65536/2048/iterations:1\n"; + Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_alignment.xml", + "--bionic_iterations=100"}); +} diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp index c90dfadce..4c6d5ddf2 100644 --- a/benchmarks/time_benchmark.cpp +++ b/benchmarks/time_benchmark.cpp @@ -20,6 +20,7 @@ #include <unistd.h> #include <benchmark/benchmark.h> +#include "util.h" static void BM_time_clock_gettime(benchmark::State& state) { timespec t; @@ -27,7 +28,7 @@ static void BM_time_clock_gettime(benchmark::State& state) { clock_gettime(CLOCK_MONOTONIC, &t); } } -BENCHMARK(BM_time_clock_gettime); +BIONIC_BENCHMARK(BM_time_clock_gettime); static void BM_time_clock_gettime_syscall(benchmark::State& state) { timespec t; @@ -35,7 +36,7 @@ static void BM_time_clock_gettime_syscall(benchmark::State& state) { syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t); } } -BENCHMARK(BM_time_clock_gettime_syscall); +BIONIC_BENCHMARK(BM_time_clock_gettime_syscall); static void BM_time_gettimeofday(benchmark::State& state) { timeval tv; @@ -43,7 +44,7 @@ static void BM_time_gettimeofday(benchmark::State& state) { gettimeofday(&tv, nullptr); } } -BENCHMARK(BM_time_gettimeofday); +BIONIC_BENCHMARK(BM_time_gettimeofday); void BM_time_gettimeofday_syscall(benchmark::State& state) { timeval tv; @@ -51,14 +52,14 @@ void BM_time_gettimeofday_syscall(benchmark::State& state) { syscall(__NR_gettimeofday, &tv, nullptr); } } -BENCHMARK(BM_time_gettimeofday_syscall); +BIONIC_BENCHMARK(BM_time_gettimeofday_syscall); void BM_time_time(benchmark::State& state) { while (state.KeepRunning()) { time(nullptr); } } -BENCHMARK(BM_time_time); +BIONIC_BENCHMARK(BM_time_time); void BM_time_localtime(benchmark::State& state) { time_t t = time(nullptr); @@ -66,7 +67,7 @@ void BM_time_localtime(benchmark::State& state) { localtime(&t); } } -BENCHMARK(BM_time_localtime); +BIONIC_BENCHMARK(BM_time_localtime); void BM_time_localtime_r(benchmark::State& state) { time_t t = time(nullptr); @@ -75,4 +76,4 @@ void BM_time_localtime_r(benchmark::State& state) { localtime_r(&t, &tm); } } -BENCHMARK(BM_time_localtime_r); +BIONIC_BENCHMARK(BM_time_localtime_r); diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp index b78d3eb61..98e885843 100644 --- a/benchmarks/unistd_benchmark.cpp +++ b/benchmarks/unistd_benchmark.cpp @@ -18,20 +18,21 @@ #include <unistd.h> #include <benchmark/benchmark.h> +#include "util.h" static void BM_unistd_getpid(benchmark::State& state) { while (state.KeepRunning()) { getpid(); } } -BENCHMARK(BM_unistd_getpid); +BIONIC_BENCHMARK(BM_unistd_getpid); static void BM_unistd_getpid_syscall(benchmark::State& state) { while (state.KeepRunning()) { syscall(__NR_getpid); } } -BENCHMARK(BM_unistd_getpid_syscall); +BIONIC_BENCHMARK(BM_unistd_getpid_syscall); #if defined(__BIONIC__) @@ -43,7 +44,7 @@ static void BM_unistd_gettid(benchmark::State& state) { gettid_fp(); } } -BENCHMARK(BM_unistd_gettid); +BIONIC_BENCHMARK(BM_unistd_gettid); #endif @@ -52,6 +53,4 @@ void BM_unistd_gettid_syscall(benchmark::State& state) { syscall(__NR_gettid); } } -BENCHMARK(BM_unistd_gettid_syscall); - -BENCHMARK_MAIN() +BIONIC_BENCHMARK(BM_unistd_gettid_syscall); diff --git a/benchmarks/util.cpp b/benchmarks/util.cpp index d9641cfa4..9afca6f7e 100644 --- a/benchmarks/util.cpp +++ b/benchmarks/util.cpp @@ -19,11 +19,11 @@ #include <sched.h> #include <stdio.h> #include <string.h> + #include <cstdlib> -#include <vector> // This function returns a pointer less than 2 * alignment + or_mask bytes into the array. -char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask) { +char* GetAlignedMemory(char* orig_ptr, size_t alignment, size_t or_mask) { if ((alignment & (alignment - 1)) != 0) { fprintf(stderr, "warning: alignment passed into GetAlignedMemory is not a power of two.\n"); std::abort(); @@ -44,12 +44,12 @@ char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask) { return reinterpret_cast<char*>(ptr); } -char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) { +char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) { buf->resize(nbytes + 3 * alignment); return GetAlignedMemory(buf->data(), alignment, 0); } -char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) { +char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) { char* buf_aligned = GetAlignedPtr(buf, alignment, nbytes); memset(buf_aligned, fill_byte, nbytes); return buf_aligned; @@ -64,7 +64,7 @@ bool LockToCPU(int) { #else -bool LockToCPU(int cpu_to_lock) { +bool LockToCPU(long cpu_to_lock) { cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -81,7 +81,7 @@ bool LockToCPU(int cpu_to_lock) { } } } else if (!CPU_ISSET(cpu_to_lock, &cpuset)) { - printf("Cpu %d does not exist.\n", cpu_to_lock); + printf("Cpu %ld does not exist.\n", cpu_to_lock); return false; } diff --git a/benchmarks/util.h b/benchmarks/util.h index bd3d51588..c8c39e315 100644 --- a/benchmarks/util.h +++ b/benchmarks/util.h @@ -17,15 +17,43 @@ #ifndef _BIONIC_BENCHMARKS_UTIL_H_ #define _BIONIC_BENCHMARKS_UTIL_H_ +#include <map> +#include <mutex> +#include <string> #include <vector> +typedef void (*benchmark_func_t) (void); + +extern std::mutex g_map_lock; + +extern std::map<std::string, benchmark_func_t> g_str_to_func; + +static int __attribute__((unused)) EmplaceBenchmark (std::string fn_name, benchmark_func_t fn_ptr) { + g_map_lock.lock(); + g_str_to_func.emplace(std::string(fn_name), fn_ptr); + g_map_lock.unlock(); + return 0; +} + +#define BIONIC_BENCHMARK(n) \ + int _bionic_benchmark_##n __attribute__((unused)) = EmplaceBenchmark(std::string(#n), reinterpret_cast<benchmark_func_t>(n)) + +constexpr auto KB = 1024; + +typedef struct { + long cpu_to_lock; + long num_iterations; + std::string xmlpath; + std::vector<std::string> extra_benchmarks; +} bench_opts_t; + // This function returns a pointer less than 2 * alignment + or_mask bytes into the array. -char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask); +char* GetAlignedMemory(char* orig_ptr, size_t alignment, size_t or_mask); -char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes); +char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes); -char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte); +char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte); -bool LockToCPU(int cpu_to_lock); +bool LockToCPU(long cpu_to_lock); #endif // _BIONIC_BENCHMARKS_UTIL_H |