summaryrefslogtreecommitdiffstats
path: root/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/Android.mk59
-rw-r--r--benchmarks/Benchmark.cpp154
-rw-r--r--benchmarks/benchmark/Benchmark.h154
-rw-r--r--benchmarks/benchmark_main.cpp266
-rw-r--r--benchmarks/include/benchmark.h65
-rw-r--r--benchmarks/main.cpp61
-rw-r--r--benchmarks/math_benchmark.cpp121
-rw-r--r--benchmarks/property_benchmark.cpp316
-rw-r--r--benchmarks/pthread_benchmark.cpp74
-rw-r--r--benchmarks/semaphore_benchmark.cpp114
-rw-r--r--benchmarks/stdio_benchmark.cpp50
-rw-r--r--benchmarks/string_benchmark.cpp35
-rw-r--r--benchmarks/time_benchmark.cpp25
-rw-r--r--benchmarks/unistd_benchmark.cpp20
-rw-r--r--benchmarks/utils.cpp81
-rw-r--r--benchmarks/utils.h26
16 files changed, 806 insertions, 815 deletions
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index c3eb6d3..ae0541f 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -20,12 +20,29 @@ LOCAL_PATH := $(call my-dir)
# Benchmarks library, usable by projects outside this directory.
# -----------------------------------------------------------------------------
+benchmark_cflags := \
+ -O2 \
+ -fno-builtin \
+ -Wall \
+ -Wextra \
+ -Werror \
+ -Wunused \
+
+benchmark_cppflags := \
+ -std=gnu++11 \
+
+benchmarklib_src_files := \
+ Benchmark.cpp \
+ utils.cpp \
+ main.cpp \
+
include $(CLEAR_VARS)
LOCAL_MODULE := libbenchmark
-LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
-LOCAL_SRC_FILES := benchmark_main.cpp
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := $(benchmark_cflags)
+LOCAL_CPPFLAGS := $(benchmark_cppflags)
+LOCAL_SRC_FILES := $(benchmarklib_src_files)
+LOCAL_C_INCLUDES := $(benchmark_c_includes)
+LOCAL_STATIC_LIBRARIES := libutils
include $(BUILD_STATIC_LIBRARY)
# Only supported on linux systems.
@@ -33,11 +50,12 @@ ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
LOCAL_MODULE := libbenchmark
-LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
-LOCAL_SRC_FILES := benchmark_main.cpp
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := $(benchmark_cflags)
+LOCAL_CPPFLAGS := $(benchmark_cppflags)
+LOCAL_SRC_FILES := $(benchmarklib_src_files)
+LOCAL_C_INCLUDES := $(benchmark_c_includes)
LOCAL_MULTILIB := both
+LOCAL_STATIC_LIBRARIES := libutils
include $(BUILD_HOST_STATIC_LIBRARY)
endif
@@ -45,16 +63,9 @@ endif
# -----------------------------------------------------------------------------
# Benchmarks.
# -----------------------------------------------------------------------------
-
-benchmark_c_flags = \
- -O2 \
- -Wall -Wextra -Wunused \
- -Werror \
- -fno-builtin \
- -std=gnu++11 \
-
-benchmark_src_files = \
+benchmark_src_files := \
math_benchmark.cpp \
+ property_benchmark.cpp \
pthread_benchmark.cpp \
semaphore_benchmark.cpp \
stdio_benchmark.cpp \
@@ -70,9 +81,10 @@ LOCAL_MODULE := bionic-benchmarks
LOCAL_MODULE_STEM_32 := bionic-benchmarks32
LOCAL_MODULE_STEM_64 := bionic-benchmarks64
LOCAL_MULTILIB := both
-LOCAL_CFLAGS += $(benchmark_c_flags)
-LOCAL_SRC_FILES := $(benchmark_src_files) property_benchmark.cpp
-LOCAL_STATIC_LIBRARIES += libbenchmark
+LOCAL_CFLAGS := $(benchmark_cflags)
+LOCAL_CPPFLAGS := $(benchmark_cppflags)
+LOCAL_SRC_FILES := $(benchmark_src_files)
+LOCAL_STATIC_LIBRARIES := libbenchmark libutils
include $(BUILD_EXECUTABLE)
# We don't build a static benchmark executable because it's not usually
@@ -90,10 +102,11 @@ LOCAL_MODULE := bionic-benchmarks-glibc
LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
LOCAL_MULTILIB := both
-LOCAL_CFLAGS += $(benchmark_c_flags)
-LOCAL_LDFLAGS += -lrt
+LOCAL_CFLAGS := $(benchmark_cflags)
+LOCAL_CPPFLAGS := $(benchmark_cppflags)
+LOCAL_LDFLAGS := -lrt
LOCAL_SRC_FILES := $(benchmark_src_files)
-LOCAL_STATIC_LIBRARIES += libbenchmark
+LOCAL_STATIC_LIBRARIES := libbenchmark libutils
include $(BUILD_HOST_EXECUTABLE)
endif
diff --git a/benchmarks/Benchmark.cpp b/benchmarks/Benchmark.cpp
new file mode 100644
index 0000000..0eb779a
--- /dev/null
+++ b/benchmarks/Benchmark.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2012 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 <inttypes.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <string>
+#include <vector>
+
+#include <utils/stringprintf.h>
+
+#include <benchmark/Benchmark.h>
+
+#include "utils.h"
+
+namespace testing {
+
+static uint64_t NanoTime() {
+ struct timespec t;
+ t.tv_sec = t.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
+}
+
+std::vector<Benchmark*>& Benchmark::List() {
+ static std::vector<Benchmark*> list;
+ return list;
+}
+
+size_t Benchmark::MaxNameColumnWidth() {
+ size_t max = 20;
+ for (auto& benchmark : List()) {
+ max = std::max(max, benchmark->NameColumnWidth());
+ }
+ return max;
+}
+
+bool Benchmark::RunAll(std::vector<regex_t*>& regs) {
+ bool ran_benchmark = false;
+ for (auto& benchmark : List()) {
+ if (benchmark->ShouldRun(regs)) {
+ if (!ran_benchmark) {
+ printf("%-*s %10s %10s\n", MaxNameColumnWidth(), "", "iterations", "ns/op");
+ ran_benchmark = true;
+ }
+ benchmark->RunAll();
+ }
+ }
+ return ran_benchmark;
+}
+
+bool Benchmark::ShouldRun(std::vector<regex_t*>& regs) {
+ if (regs.empty()) {
+ return true;
+ }
+
+ for (const auto& re : regs) {
+ if (regexec(re, Name().c_str(), 0, NULL, 0) != REG_NOMATCH) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Benchmark::StopBenchmarkTiming() {
+ if (start_time_ns_ != 0) {
+ total_time_ns_ += NanoTime() - start_time_ns_;
+ }
+ start_time_ns_ = 0;
+}
+
+void Benchmark::StartBenchmarkTiming() {
+ if (start_time_ns_ == 0) {
+ start_time_ns_ = NanoTime();
+ }
+}
+
+std::string BenchmarkWithoutArg::GetNameStr(void*) {
+ return Name();
+}
+
+template <>
+std::string BenchmarkWithArg<int>::GetNameStr(int arg) {
+ return Name() + "/" + PrettyInt(arg, 2);
+}
+
+template <>
+std::string BenchmarkWithArg<double>::GetNameStr(double arg) {
+ return Name() + "/" + android::StringPrintf("%0.6f", arg);
+}
+
+template<typename T>
+void BenchmarkT<T>::RunWithArg(T arg) {
+ int new_iterations = 1;
+ int iterations;
+ while (new_iterations < 1e8) {
+ bytes_processed_ = 0;
+ total_time_ns_ = 0;
+ start_time_ns_ = 0;
+
+ iterations = new_iterations;
+ RunIterations(iterations, arg);
+ if (total_time_ns_ >= 1e9) {
+ break;
+ }
+
+ if (total_time_ns_/iterations == 0) {
+ new_iterations = 1e9;
+ } else {
+ new_iterations = 1e9/ (total_time_ns_/iterations);
+ }
+ new_iterations = std::max(iterations + 1,
+ std::min(new_iterations + new_iterations/2, 100*iterations));
+
+ new_iterations = Round(new_iterations);
+ }
+
+ printf("%-*s %10s %10" PRId64, MaxNameColumnWidth(), GetNameStr(arg).c_str(),
+ PrettyInt(iterations, 10).c_str(), total_time_ns_/iterations);
+
+ if (total_time_ns_ > 0 && bytes_processed_ > 0) {
+ double gib_processed = static_cast<double>(bytes_processed_)/1e9;
+ double seconds = static_cast<double>(total_time_ns_)/1e9;
+ printf(" %8.3f GiB/s", gib_processed/seconds);
+ }
+ printf("\n");
+ fflush(stdout);
+}
+
+template class BenchmarkT<int>;
+template class BenchmarkT<double>;
+template class BenchmarkT<void*>;
+
+template class BenchmarkWithArg<int>;
+template class BenchmarkWithArg<double>;
+
+} // namespace testing
diff --git a/benchmarks/benchmark/Benchmark.h b/benchmarks/benchmark/Benchmark.h
new file mode 100644
index 0000000..7c208e6
--- /dev/null
+++ b/benchmarks/benchmark/Benchmark.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef BENCHMARKS_BENCHMARK_H_
+#define BENCHMARKS_BENCHMARK_H_
+
+#include <regex.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+namespace testing {
+
+class Benchmark {
+public:
+ Benchmark() {
+ List().push_back(this);
+ }
+ virtual ~Benchmark() {}
+
+ virtual std::string Name() = 0;
+
+ virtual void RunAll() = 0;
+
+ bool ShouldRun(std::vector<regex_t*>&);
+
+ void SetBenchmarkBytesProcessed(uint64_t bytes) { bytes_processed_ += bytes; }
+ void StopBenchmarkTiming();
+ void StartBenchmarkTiming();
+
+ // Run all of the benchmarks that have registered.
+ static bool RunAll(std::vector<regex_t*>&);
+
+ static std::vector<Benchmark*>& List();
+
+ static size_t MaxNameColumnWidth();
+
+protected:
+ virtual size_t NameColumnWidth() = 0;
+
+ uint64_t bytes_processed_;
+ uint64_t total_time_ns_;
+ uint64_t start_time_ns_;
+};
+
+template <typename T>
+class BenchmarkT : public Benchmark {
+public:
+ BenchmarkT() {}
+ virtual ~BenchmarkT() {}
+
+protected:
+ void RunWithArg(T arg);
+ virtual void RunIterations(int, T) = 0;
+ virtual std::string GetNameStr(T) = 0;
+};
+
+class BenchmarkWithoutArg : public BenchmarkT<void*> {
+public:
+ BenchmarkWithoutArg() {}
+ virtual ~BenchmarkWithoutArg() {}
+
+protected:
+ virtual void RunAll() override {
+ RunWithArg(nullptr);
+ }
+
+ virtual void RunIterations(int iters, void*) override {
+ Run(iters);
+ }
+
+ virtual void Run(int) = 0;
+
+ virtual size_t NameColumnWidth() override {
+ return Name().size();
+ }
+
+ virtual std::string GetNameStr(void *) override;
+};
+
+template<typename T>
+class BenchmarkWithArg : public BenchmarkT<T> {
+public:
+ BenchmarkWithArg() {}
+ virtual ~BenchmarkWithArg() {}
+
+ BenchmarkWithArg* Arg(T arg) {
+ args_.push_back(arg);
+ return this;
+ }
+
+protected:
+ virtual size_t NameColumnWidth() override {
+ size_t max = 0;
+ for (const auto arg : args_) {
+ max = std::max(max, GetNameStr(arg).size());
+ }
+ return max;
+ }
+
+ std::string GetNameStr(T arg) override;
+
+ virtual void RunAll() override {
+ for (T arg : args_) {
+ BenchmarkT<T>::RunWithArg(arg);
+ }
+ }
+
+ virtual void RunIterations(int iters, T arg) override {
+ Run(iters, arg);
+ }
+
+ virtual void Run(int iters, T arg) = 0;
+
+private:
+ std::vector<T> args_;
+};
+
+} // namespace testing
+
+#define BENCHMARK_START(f, super_class) \
+ class f : public super_class { \
+ public: \
+ f() {} \
+ virtual ~f() {} \
+ virtual std::string Name() override { return #f; } \
+
+#define BENCHMARK_NO_ARG(f) \
+ BENCHMARK_START(f, ::testing::BenchmarkWithoutArg) \
+ virtual void Run(int) override; \
+ }; \
+ static ::testing::Benchmark* __benchmark_##f = new f()
+
+#define BENCHMARK_WITH_ARG(f, arg_type) \
+ BENCHMARK_START(f, ::testing::BenchmarkWithArg<arg_type>) \
+ virtual void Run(int, arg_type) override; \
+ }; \
+ static ::testing::BenchmarkWithArg<arg_type>* __benchmark_##f = (new f())
+
+#endif // BENCHMARKS_BENCHMARK_H_
diff --git a/benchmarks/benchmark_main.cpp b/benchmarks/benchmark_main.cpp
deleted file mode 100644
index fae09be..0000000
--- a/benchmarks/benchmark_main.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2012 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 <benchmark.h>
-
-#include <regex.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <string>
-#include <vector>
-
-#include <inttypes.h>
-
-static int64_t g_bytes_processed;
-static int64_t g_benchmark_total_time_ns;
-static int64_t g_benchmark_start_time_ns;
-static int g_name_column_width = 20;
-
-typedef std::vector<::testing::Benchmark*> BenchmarkList;
-
-static BenchmarkList& Benchmarks() {
- static BenchmarkList benchmarks;
- return benchmarks;
-}
-
-// Similar to the code in art, but supporting both binary and decimal prefixes.
-static std::string PrettyInt(uint64_t count, size_t base) {
- if (base != 2 && base != 10) abort();
-
- // The byte thresholds at which we display amounts. A count is displayed
- // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
- static const uint64_t kUnitThresholds2[] = {
- 1024*1024*1024 /* Gi */, 2*1024*1024 /* Mi */, 3*1024 /* Ki */, 0,
- };
- static const uint64_t kUnitThresholds10[] = {
- 1000*1000*1000 /* G */, 2*1000*1000 /* M */, 3*1000 /* k */, 0,
- };
- static const uint64_t kAmountPerUnit2[] = { 1024*1024*1024, 1024*1024, 1024, 1 };
- static const uint64_t kAmountPerUnit10[] = { 1000*1000*1000, 1000*1000, 1000, 1 };
- static const char* const kUnitStrings2[] = { "Gi", "Mi", "Ki", "" };
- static const char* const kUnitStrings10[] = { "G", "M", "k", "" };
-
- // Which set are we using?
- const uint64_t* kUnitThresholds = ((base == 2) ? kUnitThresholds2 : kUnitThresholds10);
- const uint64_t* kAmountPerUnit = ((base == 2) ? kAmountPerUnit2 : kAmountPerUnit10);
- const char* const* kUnitStrings = ((base == 2) ? kUnitStrings2 : kUnitStrings10);
-
- size_t i = 0;
- for (; kUnitThresholds[i] != 0; ++i) {
- if (count >= kUnitThresholds[i]) {
- break;
- }
- }
- char* s = NULL;
- asprintf(&s, "%" PRId64 "%s", count / kAmountPerUnit[i], kUnitStrings[i]);
- std::string result(s);
- free(s);
- return result;
-}
-
-static int Round(int n) {
- int base = 1;
- while (base*10 < n) {
- base *= 10;
- }
- if (n < 2*base) {
- return 2*base;
- }
- if (n < 5*base) {
- return 5*base;
- }
- return 10*base;
-}
-
-static int64_t NanoTime() {
- struct timespec t;
- t.tv_sec = t.tv_nsec = 0;
- clock_gettime(CLOCK_MONOTONIC, &t);
- return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
-}
-
-namespace testing {
-
-Benchmark* Benchmark::Arg(int arg) {
- args_.push_back(arg);
- return this;
-}
-
-const char* Benchmark::Name() {
- return name_;
-}
-
-bool Benchmark::ShouldRun(int argc, char* argv[]) {
- if (argc == 1) {
- return true; // With no arguments, we run all benchmarks.
- }
- // Otherwise, we interpret each argument as a regular expression and
- // see if any of our benchmarks match.
- for (int i = 1; i < argc; i++) {
- regex_t re;
- if (regcomp(&re, argv[i], 0) != 0) {
- fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n", argv[i]);
- exit(EXIT_FAILURE);
- }
- int match = regexec(&re, name_, 0, NULL, 0);
- regfree(&re);
- if (match != REG_NOMATCH) {
- return true;
- }
- }
- return false;
-}
-
-void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int, int)) {
- name_ = name;
- fn_ = fn;
- fn_range_ = fn_range;
-
- if (fn_ == NULL && fn_range_ == NULL) {
- fprintf(stderr, "%s: missing function\n", name_);
- exit(EXIT_FAILURE);
- }
-
- Benchmarks().push_back(this);
-}
-
-void Benchmark::Run() {
- if (fn_ != NULL) {
- RunWithArg(0);
- } else {
- if (args_.empty()) {
- fprintf(stderr, "%s: no args!\n", name_);
- exit(EXIT_FAILURE);
- }
- for (size_t i = 0; i < args_.size(); ++i) {
- RunWithArg(args_[i]);
- }
- }
-}
-
-void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
- g_bytes_processed = 0;
- g_benchmark_total_time_ns = 0;
- g_benchmark_start_time_ns = NanoTime();
- if (fn_ != NULL) {
- fn_(iterations);
- } else {
- fn_range_(iterations, arg);
- }
- if (g_benchmark_start_time_ns != 0) {
- g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
- }
-}
-
-void Benchmark::RunWithArg(int arg) {
- // Run once in case it's expensive.
- int iterations = 1;
- int64_t realStartTime = NanoTime();
- RunRepeatedlyWithArg(iterations, arg);
- int64_t realTotalTime = NanoTime() - realStartTime;
- while (realTotalTime < 1e9 && iterations < 1e8) {
- int last = iterations;
- if (realTotalTime/iterations == 0) {
- iterations = 1e9;
- } else {
- iterations = 1e9 / (realTotalTime/iterations);
- }
- iterations = std::max(last + 1, std::min(iterations + iterations/2, 100*last));
- iterations = Round(iterations);
- realStartTime = NanoTime();
- RunRepeatedlyWithArg(iterations, arg);
- realTotalTime = NanoTime() - realStartTime;
- }
-
- char throughput[100];
- throughput[0] = '\0';
-
- if (g_benchmark_total_time_ns > 0 && g_bytes_processed > 0) {
- double gib_processed = static_cast<double>(g_bytes_processed)/1e9;
- double seconds = static_cast<double>(g_benchmark_total_time_ns)/1e9;
- snprintf(throughput, sizeof(throughput), " %8.3f GiB/s", gib_processed/seconds);
- }
-
- char full_name[100];
- if (fn_range_ != NULL) {
- snprintf(full_name, sizeof(full_name), "%s/%s", name_, PrettyInt(arg, 2).c_str());
- } else {
- snprintf(full_name, sizeof(full_name), "%s", name_);
- }
-
- printf("%-*s %10s %10" PRId64 "%s\n",
- g_name_column_width, full_name,
- PrettyInt(iterations, 10).c_str(),
- g_benchmark_total_time_ns/iterations,
- throughput);
- fflush(stdout);
-}
-
-} // namespace testing
-
-void SetBenchmarkBytesProcessed(int64_t x) {
- g_bytes_processed = x;
-}
-
-void StopBenchmarkTiming() {
- if (g_benchmark_start_time_ns != 0) {
- g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
- }
- g_benchmark_start_time_ns = 0;
-}
-
-void StartBenchmarkTiming() {
- if (g_benchmark_start_time_ns == 0) {
- g_benchmark_start_time_ns = NanoTime();
- }
-}
-
-int main(int argc, char* argv[]) {
- if (Benchmarks().empty()) {
- fprintf(stderr, "No benchmarks registered!\n");
- exit(EXIT_FAILURE);
- }
-
- for (auto& b : Benchmarks()) {
- int name_width = static_cast<int>(strlen(b->Name()));
- g_name_column_width = std::max(g_name_column_width, name_width);
- }
-
- bool need_header = true;
- for (auto& b : Benchmarks()) {
- if (b->ShouldRun(argc, argv)) {
- if (need_header) {
- printf("%-*s %10s %10s\n", g_name_column_width, "", "iterations", "ns/op");
- fflush(stdout);
- need_header = false;
- }
- b->Run();
- }
- }
-
- if (need_header) {
- fprintf(stderr, "No matching benchmarks!\n");
- fprintf(stderr, "Available benchmarks:\n");
- for (auto& b : Benchmarks()) {
- fprintf(stderr, " %s\n", b->Name());
- }
- exit(EXIT_FAILURE);
- }
-
- return 0;
-}
diff --git a/benchmarks/include/benchmark.h b/benchmarks/include/benchmark.h
deleted file mode 100644
index 7e134a0..0000000
--- a/benchmarks/include/benchmark.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef BENCHMARKS_BENCHMARK_H_
-#define BENCHMARKS_BENCHMARK_H_
-
-#include <stdint.h>
-#include <vector>
-
-namespace testing {
-
-class Benchmark {
- public:
- Benchmark(const char* name, void (*fn)(int)) {
- Register(name, fn, NULL);
- }
-
- Benchmark(const char* name, void (*fn_range)(int, int)) {
- Register(name, NULL, fn_range);
- }
-
- Benchmark* Arg(int x);
-
- const char* Name();
-
- bool ShouldRun(int argc, char* argv[]);
- void Run();
-
- private:
- const char* name_;
-
- void (*fn_)(int);
- void (*fn_range_)(int, int);
-
- std::vector<int> args_;
-
- void Register(const char* name, void (*fn)(int), void (*fn_range)(int, int));
- void RunRepeatedlyWithArg(int iterations, int arg);
- void RunWithArg(int arg);
-};
-
-} // namespace testing
-
-void SetBenchmarkBytesProcessed(int64_t);
-void StopBenchmarkTiming();
-void StartBenchmarkTiming();
-
-#define BENCHMARK(f) \
- static ::testing::Benchmark* _benchmark_##f __attribute__((unused)) = \
- (new ::testing::Benchmark(#f, f))
-
-#endif
diff --git a/benchmarks/main.cpp b/benchmarks/main.cpp
new file mode 100644
index 0000000..b6984fc
--- /dev/null
+++ b/benchmarks/main.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 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 <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vector>
+
+#include <benchmark/Benchmark.h>
+
+int main(int argc, char* argv[]) {
+ if (::testing::Benchmark::List().empty()) {
+ fprintf(stderr, "No benchmarks registered!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ std::vector<regex_t*> regs;
+ for (int i = 1; i < argc; i++) {
+ regex_t* re = new regex_t;
+ int errcode = regcomp(re, argv[i], 0);
+ if (errcode != 0) {
+ size_t errbuf_size = regerror(errcode, re, NULL, 0);
+ if (errbuf_size > 0) {
+ char* errbuf = new char[errbuf_size];
+ regerror(errcode, re, errbuf, errbuf_size);
+ fprintf(stderr, "Couldn't compile \"%s\" as a regular expression: %s\n",
+ argv[i], errbuf);
+ } else {
+ fprintf(stderr, "Unknown compile error for \"%s\" as a regular expression!\n", argv[i]);
+ }
+ exit(EXIT_FAILURE);
+ }
+ regs.push_back(re);
+ }
+
+ if (!::testing::Benchmark::RunAll(regs)) {
+ fprintf(stderr, "No matching benchmarks!\n");
+ fprintf(stderr, "Available benchmarks:\n");
+ for (const auto& benchmark : ::testing::Benchmark::List()) {
+ fprintf(stderr, " %s\n", benchmark->Name().c_str());
+ }
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp
index 8d6dd10..4de28d1 100644
--- a/benchmarks/math_benchmark.cpp
+++ b/benchmarks/math_benchmark.cpp
@@ -14,16 +14,20 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
#include <fenv.h>
#include <math.h>
+#include <benchmark/Benchmark.h>
+
+#define AT_COMMON_VALS \
+ Arg(1234.0)->Arg(nan(""))->Arg(HUGE_VAL)->Arg(0.0)
+
// Avoid optimization.
volatile double d;
volatile double v;
-static void BM_math_sqrt(int iters) {
+BENCHMARK_NO_ARG(BM_math_sqrt);
+void BM_math_sqrt::Run(int iters) {
StartBenchmarkTiming();
d = 0.0;
@@ -34,9 +38,9 @@ static void BM_math_sqrt(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_sqrt);
-static void BM_math_log10(int iters) {
+BENCHMARK_NO_ARG(BM_math_log10);
+void BM_math_log10::Run(int iters) {
StartBenchmarkTiming();
d = 0.0;
@@ -47,9 +51,9 @@ static void BM_math_log10(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_log10);
-static void BM_math_logb(int iters) {
+BENCHMARK_NO_ARG(BM_math_logb);
+void BM_math_logb::Run(int iters) {
StartBenchmarkTiming();
d = 0.0;
@@ -60,61 +64,22 @@ static void BM_math_logb(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_logb);
-
-static void BM_math_isinf_NORMAL(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = 1234.0; // FP_NORMAL
- for (int i = 0; i < iters; ++i) {
- d += (isinf)(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_isinf_NORMAL);
-
-static void BM_math_isinf_NAN(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = nan(""); // FP_NAN
- for (int i = 0; i < iters; ++i) {
- d += (isinf)(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_isinf_NAN);
-static void BM_math_isinf_INFINITE(int iters) {
+BENCHMARK_WITH_ARG(BM_math_isinf, double)->AT_COMMON_VALS;
+void BM_math_isinf::Run(int iters, double value) {
StartBenchmarkTiming();
d = 0.0;
- v = HUGE_VAL; // FP_INFINITE
+ v = value;
for (int i = 0; i < iters; ++i) {
d += (isinf)(v);
}
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_isinf_INFINITE);
-static void BM_math_isinf_ZERO(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = 0.0; // FP_ZERO
- for (int i = 0; i < iters; ++i) {
- d += (isinf)(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_isinf_ZERO);
-
-static void BM_math_sin_fast(int iters) {
+BENCHMARK_NO_ARG(BM_math_sin_fast);
+void BM_math_sin_fast::Run(int iters) {
StartBenchmarkTiming();
d = 1.0;
@@ -124,9 +89,9 @@ static void BM_math_sin_fast(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_sin_fast);
-static void BM_math_sin_feupdateenv(int iters) {
+BENCHMARK_NO_ARG(BM_math_sin_feupdateenv);
+void BM_math_sin_feupdateenv::Run(int iters) {
StartBenchmarkTiming();
d = 1.0;
@@ -140,9 +105,9 @@ static void BM_math_sin_feupdateenv(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_sin_feupdateenv);
-static void BM_math_sin_fesetenv(int iters) {
+BENCHMARK_NO_ARG(BM_math_sin_fesetenv);
+void BM_math_sin_fesetenv::Run(int iters) {
StartBenchmarkTiming();
d = 1.0;
@@ -156,56 +121,16 @@ static void BM_math_sin_fesetenv(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_sin_fesetenv);
-
-static void BM_math_fpclassify_NORMAL(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = 1234.0; // FP_NORMAL
- for (int i = 0; i < iters; ++i) {
- d += fpclassify(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_fpclassify_NORMAL);
-
-static void BM_math_fpclassify_NAN(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = nan(""); // FP_NAN
- for (int i = 0; i < iters; ++i) {
- d += fpclassify(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_fpclassify_NAN);
-
-static void BM_math_fpclassify_INFINITE(int iters) {
- StartBenchmarkTiming();
-
- d = 0.0;
- v = HUGE_VAL; // FP_INFINITE
- for (int i = 0; i < iters; ++i) {
- d += fpclassify(v);
- }
-
- StopBenchmarkTiming();
-}
-BENCHMARK(BM_math_fpclassify_INFINITE);
-static void BM_math_fpclassify_ZERO(int iters) {
+BENCHMARK_WITH_ARG(BM_math_fpclassify, double)->AT_COMMON_VALS;
+void BM_math_fpclassify::Run(int iters, double value) {
StartBenchmarkTiming();
d = 0.0;
- v = 0.0; // FP_ZERO
+ v = value;
for (int i = 0; i < iters; ++i) {
d += fpclassify(v);
}
StopBenchmarkTiming();
}
-BENCHMARK(BM_math_fpclassify_ZERO);
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 0802b4c..944cd68 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -14,19 +14,21 @@
* limitations under the License.
*/
-#include "benchmark.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string>
+
+#if defined(__BIONIC__)
+
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
-#include <vector>
-#include <string>
+#include <benchmark/Benchmark.h>
-extern void *__system_property_area__;
+extern void* __system_property_area__;
// Do not exceed 512, that is about the largest number of properties
// that can be created with the current property area size.
@@ -34,200 +36,198 @@ extern void *__system_property_area__;
Arg(1)->Arg(4)->Arg(16)->Arg(64)->Arg(128)->Arg(256)->Arg(512)
struct LocalPropertyTestState {
- LocalPropertyTestState(int nprops) : nprops(nprops), valid(false) {
- static const char prop_name_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
+ LocalPropertyTestState(int nprops) : nprops(nprops), valid(false) {
+ static const char prop_name_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
- const char* android_data = getenv("ANDROID_DATA");
- if (android_data == NULL) {
- printf("ANDROID_DATA environment variable not set\n");
- return;
- }
- char dir_template[PATH_MAX];
- snprintf(dir_template, sizeof(dir_template), "%s/local/tmp/prop-XXXXXX", android_data);
- char *dirname = mkdtemp(dir_template);
- if (!dirname) {
- printf("making temp file for test state failed (is %s/local/tmp writable?): %s\n",
- android_data, strerror(errno));
- return;
- }
+ const char* android_data = getenv("ANDROID_DATA");
+ if (android_data == NULL) {
+ printf("ANDROID_DATA environment variable not set\n");
+ return;
+ }
+ char dir_template[PATH_MAX];
+ snprintf(dir_template, sizeof(dir_template), "%s/local/tmp/prop-XXXXXX", android_data);
+ char* dirname = mkdtemp(dir_template);
+ if (!dirname) {
+ printf("making temp file for test state failed (is %s/local/tmp writable?): %s\n",
+ android_data, strerror(errno));
+ return;
+ }
- old_pa = __system_property_area__;
- __system_property_area__ = NULL;
-
- pa_dirname = dirname;
- pa_filename = pa_dirname + "/__properties__";
-
- __system_property_set_filename(pa_filename.c_str());
- __system_property_area_init();
-
- names = new char* [nprops];
- name_lens = new int[nprops];
- values = new char* [nprops];
- value_lens = new int[nprops];
-
- srandom(nprops);
-
- for (int i = 0; i < nprops; i++) {
- // Make sure the name has at least 10 characters to make
- // it very unlikely to generate the same random name.
- name_lens[i] = (random() % (PROP_NAME_MAX - 10)) + 10;
- names[i] = new char[PROP_NAME_MAX + 1];
- size_t prop_name_len = sizeof(prop_name_chars) - 1;
- for (int j = 0; j < name_lens[i]; j++) {
- if (j == 0 || names[i][j-1] == '.' || j == name_lens[i] - 1) {
- // Certain values are not allowed:
- // - Don't start name with '.'
- // - Don't allow '.' to appear twice in a row
- // - Don't allow the name to end with '.'
- // This assumes that '.' is the last character in the
- // array so that decrementing the length by one removes
- // the value from the possible values.
- prop_name_len--;
- }
- names[i][j] = prop_name_chars[random() % prop_name_len];
- }
- names[i][name_lens[i]] = 0;
-
- // Make sure the value contains at least 1 character.
- value_lens[i] = (random() % (PROP_VALUE_MAX - 1)) + 1;
- values[i] = new char[PROP_VALUE_MAX];
- for (int j = 0; j < value_lens[i]; j++) {
- values[i][j] = prop_name_chars[random() % (sizeof(prop_name_chars) - 1)];
- }
-
- if (__system_property_add(names[i], name_lens[i], values[i], value_lens[i]) < 0) {
- printf("Failed to add a property, terminating...\n");
- printf("%s = %.*s\n", names[i], value_lens[i], values[i]);
- exit(1);
- }
+ old_pa = __system_property_area__;
+ __system_property_area__ = NULL;
+
+ pa_dirname = dirname;
+ pa_filename = pa_dirname + "/__properties__";
+
+ __system_property_set_filename(pa_filename.c_str());
+ __system_property_area_init();
+
+ names = new char* [nprops];
+ name_lens = new int[nprops];
+ values = new char* [nprops];
+ value_lens = new int[nprops];
+
+ srandom(nprops);
+
+ for (int i = 0; i < nprops; i++) {
+ // Make sure the name has at least 10 characters to make
+ // it very unlikely to generate the same random name.
+ name_lens[i] = (random() % (PROP_NAME_MAX - 10)) + 10;
+ names[i] = new char[PROP_NAME_MAX + 1];
+ size_t prop_name_len = sizeof(prop_name_chars) - 1;
+ for (int j = 0; j < name_lens[i]; j++) {
+ if (j == 0 || names[i][j-1] == '.' || j == name_lens[i] - 1) {
+ // Certain values are not allowed:
+ // - Don't start name with '.'
+ // - Don't allow '.' to appear twice in a row
+ // - Don't allow the name to end with '.'
+ // This assumes that '.' is the last character in the
+ // array so that decrementing the length by one removes
+ // the value from the possible values.
+ prop_name_len--;
}
-
- valid = true;
+ names[i][j] = prop_name_chars[random() % prop_name_len];
+ }
+ names[i][name_lens[i]] = 0;
+
+ // Make sure the value contains at least 1 character.
+ value_lens[i] = (random() % (PROP_VALUE_MAX - 1)) + 1;
+ values[i] = new char[PROP_VALUE_MAX];
+ for (int j = 0; j < value_lens[i]; j++) {
+ values[i][j] = prop_name_chars[random() % (sizeof(prop_name_chars) - 1)];
+ }
+
+ if (__system_property_add(names[i], name_lens[i], values[i], value_lens[i]) < 0) {
+ printf("Failed to add a property, terminating...\n");
+ printf("%s = %.*s\n", names[i], value_lens[i], values[i]);
+ exit(1);
+ }
}
- ~LocalPropertyTestState() {
- if (!valid)
- return;
+ valid = true;
+ }
- __system_property_area__ = old_pa;
+ ~LocalPropertyTestState() {
+ if (!valid)
+ return;
- __system_property_set_filename(PROP_FILENAME);
- unlink(pa_filename.c_str());
- rmdir(pa_dirname.c_str());
+ __system_property_area__ = old_pa;
- for (int i = 0; i < nprops; i++) {
- delete names[i];
- delete values[i];
- }
- delete[] names;
- delete[] name_lens;
- delete[] values;
- delete[] value_lens;
+ __system_property_set_filename(PROP_FILENAME);
+ unlink(pa_filename.c_str());
+ rmdir(pa_dirname.c_str());
+
+ for (int i = 0; i < nprops; i++) {
+ delete names[i];
+ delete values[i];
}
+ delete[] names;
+ delete[] name_lens;
+ delete[] values;
+ delete[] value_lens;
+ }
public:
- const int nprops;
- char **names;
- int *name_lens;
- char **values;
- int *value_lens;
- bool valid;
+ const int nprops;
+ char** names;
+ int* name_lens;
+ char** values;
+ int* value_lens;
+ bool valid;
private:
- std::string pa_dirname;
- std::string pa_filename;
- void *old_pa;
+ std::string pa_dirname;
+ std::string pa_filename;
+ void* old_pa;
};
-static void BM_property_get(int iters, int nprops)
-{
- StopBenchmarkTiming();
+BENCHMARK_WITH_ARG(BM_property_get, int)->TEST_NUM_PROPS;
+void BM_property_get::Run(int iters, int nprops) {
+ StopBenchmarkTiming();
- LocalPropertyTestState pa(nprops);
- char value[PROP_VALUE_MAX];
+ LocalPropertyTestState pa(nprops);
+ char value[PROP_VALUE_MAX];
- if (!pa.valid)
- return;
+ if (!pa.valid)
+ return;
- srandom(iters * nprops);
+ srandom(iters * nprops);
- StartBenchmarkTiming();
+ StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
- __system_property_get(pa.names[random() % nprops], value);
- }
- StopBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ __system_property_get(pa.names[random() % nprops], value);
+ }
+ StopBenchmarkTiming();
}
-BENCHMARK(BM_property_get)->TEST_NUM_PROPS;
-static void BM_property_find(int iters, int nprops)
-{
- StopBenchmarkTiming();
+BENCHMARK_WITH_ARG(BM_property_find, int)->TEST_NUM_PROPS;
+void BM_property_find::Run(int iters, int nprops) {
+ StopBenchmarkTiming();
- LocalPropertyTestState pa(nprops);
+ LocalPropertyTestState pa(nprops);
- if (!pa.valid)
- return;
+ if (!pa.valid)
+ return;
- srandom(iters * nprops);
+ srandom(iters * nprops);
- StartBenchmarkTiming();
+ StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
- __system_property_find(pa.names[random() % nprops]);
- }
- StopBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ __system_property_find(pa.names[random() % nprops]);
+ }
+ StopBenchmarkTiming();
}
-BENCHMARK(BM_property_find)->TEST_NUM_PROPS;
-static void BM_property_read(int iters, int nprops)
-{
- StopBenchmarkTiming();
+BENCHMARK_WITH_ARG(BM_property_read, int)->TEST_NUM_PROPS;
+void BM_property_read::Run(int iters, int nprops) {
+ StopBenchmarkTiming();
- LocalPropertyTestState pa(nprops);
+ LocalPropertyTestState pa(nprops);
- if (!pa.valid)
- return;
+ if (!pa.valid)
+ return;
- srandom(iters * nprops);
- const prop_info** pinfo = new const prop_info*[iters];
- char propvalue[PROP_VALUE_MAX];
+ srandom(iters * nprops);
+ const prop_info** pinfo = new const prop_info*[iters];
+ char propvalue[PROP_VALUE_MAX];
- for (int i = 0; i < iters; i++) {
- pinfo[i] = __system_property_find(pa.names[random() % nprops]);
- }
+ for (int i = 0; i < iters; i++) {
+ pinfo[i] = __system_property_find(pa.names[random() % nprops]);
+ }
- StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
- __system_property_read(pinfo[i], 0, propvalue);
- }
- StopBenchmarkTiming();
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ __system_property_read(pinfo[i], 0, propvalue);
+ }
+ StopBenchmarkTiming();
- delete[] pinfo;
+ delete[] pinfo;
}
-BENCHMARK(BM_property_read)->TEST_NUM_PROPS;
-static void BM_property_serial(int iters, int nprops)
-{
- StopBenchmarkTiming();
+BENCHMARK_WITH_ARG(BM_property_serial, int)->TEST_NUM_PROPS;
+void BM_property_serial::Run(int iters, int nprops) {
+ StopBenchmarkTiming();
- LocalPropertyTestState pa(nprops);
+ LocalPropertyTestState pa(nprops);
- if (!pa.valid)
- return;
+ if (!pa.valid)
+ return;
- srandom(iters * nprops);
- const prop_info** pinfo = new const prop_info*[iters];
+ srandom(iters * nprops);
+ const prop_info** pinfo = new const prop_info*[iters];
- for (int i = 0; i < iters; i++) {
- pinfo[i] = __system_property_find(pa.names[random() % nprops]);
- }
+ for (int i = 0; i < iters; i++) {
+ pinfo[i] = __system_property_find(pa.names[random() % nprops]);
+ }
- StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
- __system_property_serial(pinfo[i]);
- }
- StopBenchmarkTiming();
+ StartBenchmarkTiming();
+ for (int i = 0; i < iters; i++) {
+ __system_property_serial(pinfo[i]);
+ }
+ StopBenchmarkTiming();
- delete[] pinfo;
+ delete[] pinfo;
}
-BENCHMARK(BM_property_serial)->TEST_NUM_PROPS;
+
+#endif // __BIONIC__
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 42023e0..2f6572d 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
#include <pthread.h>
+#include <benchmark/Benchmark.h>
+
// Stop GCC optimizing out our pure function.
/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
-static void BM_pthread_self(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_self);
+void BM_pthread_self::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -30,9 +31,9 @@ static void BM_pthread_self(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_pthread_self);
-static void BM_pthread_getspecific(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_getspecific);
+void BM_pthread_getspecific::Run(int iters) {
StopBenchmarkTiming();
pthread_key_t key;
pthread_key_create(&key, NULL);
@@ -45,9 +46,9 @@ static void BM_pthread_getspecific(int iters) {
StopBenchmarkTiming();
pthread_key_delete(key);
}
-BENCHMARK(BM_pthread_getspecific);
-static void BM_pthread_setspecific(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_setspecific);
+void BM_pthread_setspecific::Run(int iters) {
StopBenchmarkTiming();
pthread_key_t key;
pthread_key_create(&key, NULL);
@@ -60,12 +61,12 @@ static void BM_pthread_setspecific(int iters) {
StopBenchmarkTiming();
pthread_key_delete(key);
}
-BENCHMARK(BM_pthread_setspecific);
static void DummyPthreadOnceInitFunction() {
}
-static void BM_pthread_once(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_once);
+void BM_pthread_once::Run(int iters) {
StopBenchmarkTiming();
pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, DummyPthreadOnceInitFunction);
@@ -77,9 +78,9 @@ static void BM_pthread_once(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_pthread_once);
-static void BM_pthread_mutex_lock(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_mutex_lock);
+void BM_pthread_mutex_lock::Run(int iters) {
StopBenchmarkTiming();
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
StartBenchmarkTiming();
@@ -91,9 +92,9 @@ static void BM_pthread_mutex_lock(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_pthread_mutex_lock);
-static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_mutex_lock_ERRORCHECK);
+void BM_pthread_mutex_lock_ERRORCHECK::Run(int iters) {
StopBenchmarkTiming();
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
StartBenchmarkTiming();
@@ -105,9 +106,9 @@ static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
-static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_mutex_lock_RECURSIVE);
+void BM_pthread_mutex_lock_RECURSIVE::Run(int iters) {
StopBenchmarkTiming();
pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
StartBenchmarkTiming();
@@ -119,9 +120,9 @@ static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
-static void BM_pthread_rw_lock_read(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_rw_lock_read);
+void BM_pthread_rw_lock_read::Run(int iters) {
StopBenchmarkTiming();
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
@@ -135,9 +136,9 @@ static void BM_pthread_rw_lock_read(int iters) {
StopBenchmarkTiming();
pthread_rwlock_destroy(&lock);
}
-BENCHMARK(BM_pthread_rw_lock_read);
-static void BM_pthread_rw_lock_write(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_rw_lock_write);
+void BM_pthread_rw_lock_write::Run(int iters) {
StopBenchmarkTiming();
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
@@ -151,13 +152,13 @@ static void BM_pthread_rw_lock_write(int iters) {
StopBenchmarkTiming();
pthread_rwlock_destroy(&lock);
}
-BENCHMARK(BM_pthread_rw_lock_write);
static void* IdleThread(void*) {
return NULL;
}
-static void BM_pthread_create(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_create);
+void BM_pthread_create::Run(int iters) {
StopBenchmarkTiming();
pthread_t thread;
@@ -168,43 +169,45 @@ static void BM_pthread_create(int iters) {
pthread_join(thread, NULL);
}
}
-BENCHMARK(BM_pthread_create);
-static void* RunThread(void*) {
- StopBenchmarkTiming();
+static void* RunThread(void* arg) {
+ ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
+ benchmark->StopBenchmarkTiming();
return NULL;
}
-static void BM_pthread_create_and_run(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_create_and_run);
+void BM_pthread_create_and_run::Run(int iters) {
StopBenchmarkTiming();
pthread_t thread;
for (int i = 0; i < iters; ++i) {
StartBenchmarkTiming();
- pthread_create(&thread, NULL, RunThread, NULL);
+ pthread_create(&thread, NULL, RunThread, this);
pthread_join(thread, NULL);
}
}
-BENCHMARK(BM_pthread_create_and_run);
-static void* ExitThread(void*) {
- StartBenchmarkTiming();
+static void* ExitThread(void* arg) {
+ ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
+ benchmark->StartBenchmarkTiming();
pthread_exit(NULL);
}
-static void BM_pthread_exit_and_join(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_exit_and_join);
+void BM_pthread_exit_and_join::Run(int iters) {
StopBenchmarkTiming();
pthread_t thread;
for (int i = 0; i < iters; ++i) {
- pthread_create(&thread, NULL, ExitThread, NULL);
+ pthread_create(&thread, NULL, ExitThread, this);
pthread_join(thread, NULL);
StopBenchmarkTiming();
}
}
-BENCHMARK(BM_pthread_exit_and_join);
-static void BM_pthread_key_create(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_key_create);
+void BM_pthread_key_create::Run(int iters) {
StopBenchmarkTiming();
pthread_key_t key;
@@ -215,9 +218,9 @@ static void BM_pthread_key_create(int iters) {
pthread_key_delete(key);
}
}
-BENCHMARK(BM_pthread_key_create);
-static void BM_pthread_key_delete(int iters) {
+BENCHMARK_NO_ARG(BM_pthread_key_delete);
+void BM_pthread_key_delete::Run(int iters) {
StopBenchmarkTiming();
pthread_key_t key;
@@ -228,4 +231,3 @@ static void BM_pthread_key_delete(int iters) {
StopBenchmarkTiming();
}
}
-BENCHMARK(BM_pthread_key_delete);
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index 974b046..8dd5684 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
#include <pthread.h>
#include <semaphore.h>
#include <stdatomic.h>
#include <stdio.h>
-static void BM_semaphore_sem_getvalue(int iters) {
+#include <benchmark/Benchmark.h>
+
+BENCHMARK_NO_ARG(BM_semaphore_sem_getvalue);
+void BM_semaphore_sem_getvalue::Run(int iters) {
StopBenchmarkTiming();
sem_t semaphore;
sem_init(&semaphore, 1, 1);
@@ -34,9 +35,9 @@ static void BM_semaphore_sem_getvalue(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_semaphore_sem_getvalue);
-static void BM_semaphore_sem_wait_sem_post(int iters) {
+BENCHMARK_NO_ARG(BM_semaphore_sem_wait_sem_post);
+void BM_semaphore_sem_wait_sem_post::Run(int iters) {
StopBenchmarkTiming();
sem_t semaphore;
sem_init(&semaphore, 1, 1);
@@ -49,7 +50,6 @@ static void BM_semaphore_sem_wait_sem_post(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_semaphore_sem_wait_sem_post);
/*
* This test reports the overhead of the underlying futex wake syscall on
@@ -87,7 +87,8 @@ static void *BM_semaphore_sem_post_start_thread(void *obj) {
return NULL;
}
-static void BM_semaphore_sem_post(int iters) {
+BENCHMARK_NO_ARG(BM_semaphore_sem_post);
+void BM_semaphore_sem_post::Run(int iters) {
StopBenchmarkTiming();
sem_t semaphore;
@@ -100,9 +101,6 @@ static void BM_semaphore_sem_post(int iters) {
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#ifdef PTHREAD_SET_INHERIT_SCHED
- pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-#endif
pthread_t pthread;
pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
pthread_attr_destroy(&attr);
@@ -143,99 +141,3 @@ static void BM_semaphore_sem_post(int iters) {
sched_yield();
} while (!BM_semaphore_sem_post_running);
}
-BENCHMARK(BM_semaphore_sem_post);
-
-/*
- * This test reports the overhead of sem_post to sem_wake. A circle of
- * num_semaphore - 1 threads are run on a set of semaphores to measure the
- * activity. One can calculate the sem_wake overhead alone by:
- *
- * BM_semaphore_sem_post_sem_wait - BM_semaphore_sem_post - BM_time_clock_gettime
- *
- * Differences will result if there are more threads than active processors,
- * there will be delay induced when scheduling the processes. This cost is
- * measured by trying different values of num_semaphore. The governor selected
- * will have a major impact on the results for a large number of threads.
- *
- * To reduce the chances for threads racing ahead and not triggering the
- * futex, for example the background threads finish their job before the
- * sem_wait is hit in the main thread, the background threads will run at
- * batch priority and the main thread at fifo priority. This should generally
- * guarantee the main thread completes its task of priming itself with the
- * sem_wait before the other threads can start. In practice without the
- * sched mechanics here, this works on Android configured kernels, this is
- * insurance for wacky(tm) sched configurations.
- */
-static void *BM_semaphore_sem_post_sem_wait_start_thread(void *obj) {
- sem_t *semaphore = reinterpret_cast<sem_t *>(obj);
-
- while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
- sem_post(semaphore + 1);
- }
- --BM_semaphore_sem_post_running;
- return NULL;
-}
-
-static void BM_semaphore_sem_post_sem_wait_num(int iters, int num_semaphore) {
- StopBenchmarkTiming();
-
- sem_t semaphore[num_semaphore];
-
- for (int i = 0; i < num_semaphore; ++i) {
- sem_init(semaphore + i, 0, 0);
- }
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- BM_semaphore_sem_post_running = 1;
- struct sched_param param = { 0, };
- pthread_attr_setschedparam(&attr, &param);
- pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#ifdef PTHREAD_SET_INHERIT_SCHED
- pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-#endif
- for (int i = 0; i < (num_semaphore - 1); ++i) {
- pthread_t pthread;
- pthread_create(&pthread, &attr, BM_semaphore_sem_post_sem_wait_start_thread, semaphore + i);
- }
- pthread_attr_destroy(&attr);
- sched_yield();
-
- param.sched_priority = 1;
- sched_setscheduler((pid_t)0, SCHED_FIFO, &param);
-
- StartBenchmarkTiming();
-
- for (int i = 0; i < iters; i += num_semaphore) {
- sem_post(semaphore);
- sem_wait(semaphore + num_semaphore - 1);
- }
-
- StopBenchmarkTiming();
-
- param.sched_priority = 0;
- sched_setscheduler((pid_t)0, SCHED_OTHER, &param);
-
- if (BM_semaphore_sem_post_running > 0) {
- BM_semaphore_sem_post_running = 0;
- }
- for (int i = 0;
- (i < (10 * num_semaphore)) && (BM_semaphore_sem_post_running > (1 - num_semaphore));
- ++i) {
- for (int j = 0; j < (num_semaphore - 1); ++j) {
- sem_post(semaphore + j);
- }
- sched_yield();
- }
-}
-
-static void BM_semaphore_sem_post_sem_wait_low(int iters) {
- BM_semaphore_sem_post_sem_wait_num(iters, 2);
-}
-BENCHMARK(BM_semaphore_sem_post_sem_wait_low);
-
-static void BM_semaphore_sem_post_sem_wait_high(int iters) {
- BM_semaphore_sem_post_sem_wait_num(iters, 100);
-}
-BENCHMARK(BM_semaphore_sem_post_sem_wait_high);
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 5658a50..342e561 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
#include <stdio.h>
#include <stdio_ext.h>
+#include <benchmark/Benchmark.h>
+
#define KB 1024
#define MB 1024*KB
@@ -27,12 +27,12 @@
Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
template <typename Fn>
-static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
- StopBenchmarkTiming();
+void ReadWriteTest(::testing::Benchmark* benchmark, int iters, int chunk_size, Fn f, bool buffered) {
+ benchmark->StopBenchmarkTiming();
FILE* fp = fopen("/dev/zero", "rw");
__fsetlocking(fp, FSETLOCKING_BYCALLER);
char* buf = new char[chunk_size];
- StartBenchmarkTiming();
+ benchmark->StartBenchmarkTiming();
if (!buffered) {
setvbuf(fp, 0, _IONBF, 0);
@@ -42,31 +42,31 @@ static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
f(buf, chunk_size, 1, fp);
}
- StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
+ benchmark->StopBenchmarkTiming();
+ benchmark->SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
delete[] buf;
fclose(fp);
}
-static void BM_stdio_fread(int iters, int chunk_size) {
- ReadWriteTest(iters, chunk_size, fread, true);
+BENCHMARK_WITH_ARG(BM_stdio_fread, int)->AT_COMMON_SIZES;
+void BM_stdio_fread::Run(int iters, int chunk_size) {
+ ReadWriteTest(this, iters, chunk_size, fread, true);
}
-BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
-static void BM_stdio_fwrite(int iters, int chunk_size) {
- ReadWriteTest(iters, chunk_size, fwrite, true);
+BENCHMARK_WITH_ARG(BM_stdio_fwrite, int)->AT_COMMON_SIZES;
+void BM_stdio_fwrite::Run(int iters, int chunk_size) {
+ ReadWriteTest(this, iters, chunk_size, fwrite, true);
}
-BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
-static void BM_stdio_fread_unbuffered(int iters, int chunk_size) {
- ReadWriteTest(iters, chunk_size, fread, false);
+BENCHMARK_WITH_ARG(BM_stdio_fread_unbuffered, int)->AT_COMMON_SIZES;
+void BM_stdio_fread_unbuffered::Run(int iters, int chunk_size) {
+ ReadWriteTest(this, iters, chunk_size, fread, false);
}
-BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
-static void BM_stdio_fwrite_unbuffered(int iters, int chunk_size) {
- ReadWriteTest(iters, chunk_size, fwrite, false);
+BENCHMARK_WITH_ARG(BM_stdio_fwrite_unbuffered, int)->AT_COMMON_SIZES;
+void BM_stdio_fwrite_unbuffered::Run(int iters, int chunk_size) {
+ ReadWriteTest(this, iters, chunk_size, fwrite, false);
}
-BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
static void FopenFgetsFclose(int iters, bool no_locking) {
char buf[1024];
@@ -78,12 +78,16 @@ static void FopenFgetsFclose(int iters, bool no_locking) {
}
}
-static void BM_stdio_fopen_fgets_fclose_locking(int iters) {
+BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_locking);
+void BM_stdio_fopen_fgets_fclose_locking::Run(int iters) {
+ StartBenchmarkTiming();
FopenFgetsFclose(iters, false);
+ StopBenchmarkTiming();
}
-BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
-static void BM_stdio_fopen_fgets_fclose_no_locking(int iters) {
+BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_no_locking);
+void BM_stdio_fopen_fgets_fclose_no_locking::Run(int iters) {
+ StartBenchmarkTiming();
FopenFgetsFclose(iters, true);
+ StopBenchmarkTiming();
}
-BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 536e253..866aa00 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
+#include <stdint.h>
#include <string.h>
+#include <benchmark/Benchmark.h>
+
#define KB 1024
#define MB 1024*KB
@@ -26,7 +27,8 @@
// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
-static void BM_string_memcmp(int iters, int nbytes) {
+BENCHMARK_WITH_ARG(BM_string_memcmp, int)->AT_COMMON_SIZES;
+void BM_string_memcmp::Run(int iters, int nbytes) {
StopBenchmarkTiming();
char* src = new char[nbytes]; char* dst = new char[nbytes];
memset(src, 'x', nbytes);
@@ -39,13 +41,13 @@ static void BM_string_memcmp(int iters, int nbytes) {
}
StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
+ SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
delete[] src;
delete[] dst;
}
-BENCHMARK(BM_string_memcmp)->AT_COMMON_SIZES;
-static void BM_string_memcpy(int iters, int nbytes) {
+BENCHMARK_WITH_ARG(BM_string_memcpy, int)->AT_COMMON_SIZES;
+void BM_string_memcpy::Run(int iters, int nbytes) {
StopBenchmarkTiming();
char* src = new char[nbytes]; char* dst = new char[nbytes];
memset(src, 'x', nbytes);
@@ -56,13 +58,13 @@ static void BM_string_memcpy(int iters, int nbytes) {
}
StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
+ SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
delete[] src;
delete[] dst;
}
-BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
-static void BM_string_memmove(int iters, int nbytes) {
+BENCHMARK_WITH_ARG(BM_string_memmove, int)->AT_COMMON_SIZES;
+void BM_string_memmove::Run(int iters, int nbytes) {
StopBenchmarkTiming();
char* buf = new char[nbytes + 64];
memset(buf, 'x', nbytes + 64);
@@ -73,12 +75,12 @@ static void BM_string_memmove(int iters, int nbytes) {
}
StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
+ SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
delete[] buf;
}
-BENCHMARK(BM_string_memmove)->AT_COMMON_SIZES;
-static void BM_string_memset(int iters, int nbytes) {
+BENCHMARK_WITH_ARG(BM_string_memset, int)->AT_COMMON_SIZES;
+void BM_string_memset::Run(int iters, int nbytes) {
StopBenchmarkTiming();
char* dst = new char[nbytes];
StartBenchmarkTiming();
@@ -88,12 +90,12 @@ static void BM_string_memset(int iters, int nbytes) {
}
StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
+ SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
delete[] dst;
}
-BENCHMARK(BM_string_memset)->AT_COMMON_SIZES;
-static void BM_string_strlen(int iters, int nbytes) {
+BENCHMARK_WITH_ARG(BM_string_strlen, int)->AT_COMMON_SIZES;
+void BM_string_strlen::Run(int iters, int nbytes) {
StopBenchmarkTiming();
char* s = new char[nbytes];
memset(s, 'x', nbytes);
@@ -106,7 +108,6 @@ static void BM_string_strlen(int iters, int nbytes) {
}
StopBenchmarkTiming();
- SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
+ SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
delete[] s;
}
-BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp
index f093ec1..6688bbc 100644
--- a/benchmarks/time_benchmark.cpp
+++ b/benchmarks/time_benchmark.cpp
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
-#include <unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <time.h>
-static void BM_time_clock_gettime(int iters) {
+#include <benchmark/Benchmark.h>
+
+BENCHMARK_NO_ARG(BM_time_clock_gettime);
+void BM_time_clock_gettime::Run(int iters) {
StartBenchmarkTiming();
timespec t;
@@ -31,9 +31,9 @@ static void BM_time_clock_gettime(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_time_clock_gettime);
-static void BM_time_clock_gettime_syscall(int iters) {
+BENCHMARK_NO_ARG(BM_time_clock_gettime_syscall);
+void BM_time_clock_gettime_syscall::Run(int iters) {
StartBenchmarkTiming();
timespec t;
@@ -43,9 +43,9 @@ static void BM_time_clock_gettime_syscall(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_time_clock_gettime_syscall);
-static void BM_time_gettimeofday(int iters) {
+BENCHMARK_NO_ARG(BM_time_gettimeofday);
+void BM_time_gettimeofday::Run(int iters) {
StartBenchmarkTiming();
timeval tv;
@@ -55,9 +55,9 @@ static void BM_time_gettimeofday(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_time_gettimeofday);
-static void BM_time_gettimeofday_syscall(int iters) {
+BENCHMARK_NO_ARG(BM_time_gettimeofday_syscall);
+void BM_time_gettimeofday_syscall::Run(int iters) {
StartBenchmarkTiming();
timeval tv;
@@ -67,9 +67,9 @@ static void BM_time_gettimeofday_syscall(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_time_gettimeofday_syscall);
-static void BM_time_time(int iters) {
+BENCHMARK_NO_ARG(BM_time_time);
+void BM_time_time::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -78,4 +78,3 @@ static void BM_time_time(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_time_time);
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
index 94be1dd..09ca0e6 100644
--- a/benchmarks/unistd_benchmark.cpp
+++ b/benchmarks/unistd_benchmark.cpp
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-#include "benchmark.h"
-
#include <sys/syscall.h>
#include <unistd.h>
-static void BM_unistd_getpid(int iters) {
+#include <benchmark/Benchmark.h>
+
+BENCHMARK_NO_ARG(BM_unistd_getpid);
+void BM_unistd_getpid::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -28,9 +29,9 @@ static void BM_unistd_getpid(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_unistd_getpid);
-static void BM_unistd_getpid_syscall(int iters) {
+BENCHMARK_NO_ARG(BM_unistd_getpid_syscall);
+void BM_unistd_getpid_syscall::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -39,14 +40,14 @@ static void BM_unistd_getpid_syscall(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_unistd_getpid_syscall);
#if defined(__BIONIC__)
// Stop GCC optimizing out our pure function.
/* Must not be static! */ pid_t (*gettid_fp)() = gettid;
-static void BM_unistd_gettid(int iters) {
+BENCHMARK_NO_ARG(BM_unistd_gettid);
+void BM_unistd_gettid::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -55,11 +56,11 @@ static void BM_unistd_gettid(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_unistd_gettid);
#endif
-static void BM_unistd_gettid_syscall(int iters) {
+BENCHMARK_NO_ARG(BM_unistd_gettid_syscall);
+void BM_unistd_gettid_syscall::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; ++i) {
@@ -68,4 +69,3 @@ static void BM_unistd_gettid_syscall(int iters) {
StopBenchmarkTiming();
}
-BENCHMARK(BM_unistd_gettid_syscall);
diff --git a/benchmarks/utils.cpp b/benchmarks/utils.cpp
new file mode 100644
index 0000000..863b9db
--- /dev/null
+++ b/benchmarks/utils.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012 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 <inttypes.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <string>
+
+#include "utils.h"
+
+int Round(int n) {
+ int base = 1;
+ while (base*10 < n) {
+ base *= 10;
+ }
+ if (n < 2*base) {
+ return 2*base;
+ }
+ if (n < 5*base) {
+ return 5*base;
+ }
+ return 10*base;
+}
+
+// Similar to the code in art, but supporting both binary and decimal prefixes.
+std::string PrettyInt(long value, size_t base) {
+ if (base != 2 && base != 10) abort();
+
+ uint64_t count = static_cast<uint64_t>(value);
+ bool negative_number = false;
+ if (value < 0) {
+ negative_number = true;
+ count = static_cast<uint64_t>(-value);
+ }
+
+ // The byte thresholds at which we display amounts. A count is displayed
+ // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
+ static const uint64_t kUnitThresholds2[] = {
+ 1024*1024*1024 /* Gi */, 2*1024*1024 /* Mi */, 3*1024 /* Ki */, 0,
+ };
+ static const uint64_t kUnitThresholds10[] = {
+ 1000*1000*1000 /* G */, 2*1000*1000 /* M */, 3*1000 /* k */, 0,
+ };
+ static const uint64_t kAmountPerUnit2[] = { 1024*1024*1024, 1024*1024, 1024, 1 };
+ static const uint64_t kAmountPerUnit10[] = { 1000*1000*1000, 1000*1000, 1000, 1 };
+ static const char* const kUnitStrings2[] = { "Gi", "Mi", "Ki", "" };
+ static const char* const kUnitStrings10[] = { "G", "M", "k", "" };
+
+ // Which set are we using?
+ const uint64_t* kUnitThresholds = ((base == 2) ? kUnitThresholds2 : kUnitThresholds10);
+ const uint64_t* kAmountPerUnit = ((base == 2) ? kAmountPerUnit2 : kAmountPerUnit10);
+ const char* const* kUnitStrings = ((base == 2) ? kUnitStrings2 : kUnitStrings10);
+
+ size_t i = 0;
+ for (; kUnitThresholds[i] != 0; ++i) {
+ if (count >= kUnitThresholds[i]) {
+ break;
+ }
+ }
+ char* s = NULL;
+ asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
+ count / kAmountPerUnit[i], kUnitStrings[i]);
+ std::string result(s);
+ free(s);
+ return result;
+}
diff --git a/benchmarks/utils.h b/benchmarks/utils.h
new file mode 100644
index 0000000..c3c64ba
--- /dev/null
+++ b/benchmarks/utils.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef BENCHMARKS_UTILS_H
+#define BENCHMARKS_UTILS_H
+
+#include <stddef.h>
+#include <string>
+
+int Round(int n);
+std::string PrettyInt(long value, size_t base);
+
+#endif // BENCHMARKS_UTILS_H