Merge "Improve benchmarking tool, add a few math benchmarks."
diff --git a/tests/Android.mk b/tests/Android.mk
index ed1df6e..3217a4d 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -26,9 +26,11 @@
-O2 \
-Wall -Wextra \
-Werror \
+ -fno-builtin \
benchmark_src_files = \
benchmark_main.cpp \
+ math_benchmark.cpp \
string_benchmark.cpp \
# Build benchmarks for the device (with bionic's .so). Run with:
diff --git a/tests/benchmark.h b/tests/benchmark.h
index 70d4c63..d7af50f 100644
--- a/tests/benchmark.h
+++ b/tests/benchmark.h
@@ -32,6 +32,8 @@
Benchmark* Arg(int x);
+ const char* Name();
+
bool ShouldRun(int argc, char* argv[]);
void Run();
diff --git a/tests/benchmark_main.cpp b/tests/benchmark_main.cpp
index 4fbeb07..e15a688 100644
--- a/tests/benchmark_main.cpp
+++ b/tests/benchmark_main.cpp
@@ -59,6 +59,10 @@
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.
@@ -94,12 +98,16 @@
}
void Benchmark::Run() {
- 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]);
+ 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]);
+ }
}
}
@@ -180,18 +188,31 @@
int main(int argc, char* argv[]) {
if (gBenchmarks.empty()) {
- fprintf(stderr, "no benchmarks!\n");
+ fprintf(stderr, "No benchmarks registered!\n");
exit(EXIT_FAILURE);
}
- printf("%-20s %10s %10s\n", "", "iterations", "ns/op");
- fflush(stdout);
-
+ bool need_header = true;
for (BenchmarkMapIt it = gBenchmarks.begin(); it != gBenchmarks.end(); ++it) {
::testing::Benchmark* b = it->second;
if (b->ShouldRun(argc, argv)) {
+ if (need_header) {
+ printf("%-20s %10s %10s\n", "", "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 (BenchmarkMapIt it = gBenchmarks.begin(); it != gBenchmarks.end(); ++it) {
+ fprintf(stderr, " %s\n", it->second->Name());
+ }
+ exit(EXIT_FAILURE);
+ }
+
return 0;
}
diff --git a/tests/math_benchmark.cpp b/tests/math_benchmark.cpp
new file mode 100644
index 0000000..a8c1cfa
--- /dev/null
+++ b/tests/math_benchmark.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 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 <math.h>
+
+// Avoid optimization.
+double d;
+double v;
+
+static void BM_math_sqrt(int iters) {
+ StartBenchmarkTiming();
+
+ d = 0.0;
+ v = 2.0;
+ for (int i = 0; i < iters; ++i) {
+ d += sqrt(v);
+ }
+
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_math_sqrt);
+
+static void BM_math_log10(int iters) {
+ StartBenchmarkTiming();
+
+ d = 0.0;
+ v = 1234.0;
+ for (int i = 0; i < iters; ++i) {
+ d += log10(v);
+ }
+
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_math_log10);
+
+static void BM_math_logb(int iters) {
+ StartBenchmarkTiming();
+
+ d = 0.0;
+ v = 1234.0;
+ for (int i = 0; i < iters; ++i) {
+ d += logb(v);
+ }
+
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_math_logb);
diff --git a/tests/string_benchmark.cpp b/tests/string_benchmark.cpp
index 7ac8e98..536e253 100644
--- a/tests/string_benchmark.cpp
+++ b/tests/string_benchmark.cpp
@@ -26,7 +26,7 @@
// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
-static void BM_memcmp(int iters, int nbytes) {
+static void BM_string_memcmp(int iters, int nbytes) {
StopBenchmarkTiming();
char* src = new char[nbytes]; char* dst = new char[nbytes];
memset(src, 'x', nbytes);
@@ -34,7 +34,7 @@
StartBenchmarkTiming();
volatile int c __attribute__((unused)) = 0;
- for (int i = 0; i < iters; i++) {
+ for (int i = 0; i < iters; ++i) {
c += memcmp(dst, src, nbytes);
}
@@ -43,15 +43,15 @@
delete[] src;
delete[] dst;
}
-BENCHMARK(BM_memcmp)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memcmp)->AT_COMMON_SIZES;
-static void BM_memcpy(int iters, int nbytes) {
+static void BM_string_memcpy(int iters, int nbytes) {
StopBenchmarkTiming();
char* src = new char[nbytes]; char* dst = new char[nbytes];
memset(src, 'x', nbytes);
StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
+ for (int i = 0; i < iters; ++i) {
memcpy(dst, src, nbytes);
}
@@ -60,15 +60,15 @@
delete[] src;
delete[] dst;
}
-BENCHMARK(BM_memcpy)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
-static void BM_memmove(int iters, int nbytes) {
+static void BM_string_memmove(int iters, int nbytes) {
StopBenchmarkTiming();
char* buf = new char[nbytes + 64];
memset(buf, 'x', nbytes + 64);
StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
+ for (int i = 0; i < iters; ++i) {
memmove(buf, buf + 1, nbytes); // Worst-case overlap.
}
@@ -76,14 +76,14 @@
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
delete[] buf;
}
-BENCHMARK(BM_memmove)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memmove)->AT_COMMON_SIZES;
-static void BM_memset(int iters, int nbytes) {
+static void BM_string_memset(int iters, int nbytes) {
StopBenchmarkTiming();
char* dst = new char[nbytes];
StartBenchmarkTiming();
- for (int i = 0; i < iters; i++) {
+ for (int i = 0; i < iters; ++i) {
memset(dst, 0, nbytes);
}
@@ -91,9 +91,9 @@
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
delete[] dst;
}
-BENCHMARK(BM_memset)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memset)->AT_COMMON_SIZES;
-static void BM_strlen(int iters, int nbytes) {
+static void BM_string_strlen(int iters, int nbytes) {
StopBenchmarkTiming();
char* s = new char[nbytes];
memset(s, 'x', nbytes);
@@ -101,7 +101,7 @@
StartBenchmarkTiming();
volatile int c __attribute__((unused)) = 0;
- for (int i = 0; i < iters; i++) {
+ for (int i = 0; i < iters; ++i) {
c += strlen(s);
}
@@ -109,4 +109,4 @@
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
delete[] s;
}
-BENCHMARK(BM_strlen)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;