Merge "Improve benchmarking tool, add a few math benchmarks."
This commit is contained in:
commit
c9ab32e4e9
5 changed files with 112 additions and 25 deletions
|
@ -26,9 +26,11 @@ benchmark_c_flags = \
|
||||||
-O2 \
|
-O2 \
|
||||||
-Wall -Wextra \
|
-Wall -Wextra \
|
||||||
-Werror \
|
-Werror \
|
||||||
|
-fno-builtin \
|
||||||
|
|
||||||
benchmark_src_files = \
|
benchmark_src_files = \
|
||||||
benchmark_main.cpp \
|
benchmark_main.cpp \
|
||||||
|
math_benchmark.cpp \
|
||||||
string_benchmark.cpp \
|
string_benchmark.cpp \
|
||||||
|
|
||||||
# Build benchmarks for the device (with bionic's .so). Run with:
|
# Build benchmarks for the device (with bionic's .so). Run with:
|
||||||
|
|
|
@ -32,6 +32,8 @@ class Benchmark {
|
||||||
|
|
||||||
Benchmark* Arg(int x);
|
Benchmark* Arg(int x);
|
||||||
|
|
||||||
|
const char* Name();
|
||||||
|
|
||||||
bool ShouldRun(int argc, char* argv[]);
|
bool ShouldRun(int argc, char* argv[]);
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,10 @@ Benchmark* Benchmark::Arg(int arg) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Benchmark::Name() {
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
bool Benchmark::ShouldRun(int argc, char* argv[]) {
|
bool Benchmark::ShouldRun(int argc, char* argv[]) {
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
return true; // With no arguments, we run all benchmarks.
|
return true; // With no arguments, we run all benchmarks.
|
||||||
|
@ -94,6 +98,9 @@ void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int
|
||||||
}
|
}
|
||||||
|
|
||||||
void Benchmark::Run() {
|
void Benchmark::Run() {
|
||||||
|
if (fn_ != NULL) {
|
||||||
|
RunWithArg(0);
|
||||||
|
} else {
|
||||||
if (args_.empty()) {
|
if (args_.empty()) {
|
||||||
fprintf(stderr, "%s: no args!\n", name_);
|
fprintf(stderr, "%s: no args!\n", name_);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -102,6 +109,7 @@ void Benchmark::Run() {
|
||||||
RunWithArg(args_[i]);
|
RunWithArg(args_[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
|
void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
|
||||||
gBytesProcessed = 0;
|
gBytesProcessed = 0;
|
||||||
|
@ -180,18 +188,31 @@ void StartBenchmarkTiming() {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (gBenchmarks.empty()) {
|
if (gBenchmarks.empty()) {
|
||||||
fprintf(stderr, "no benchmarks!\n");
|
fprintf(stderr, "No benchmarks registered!\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%-20s %10s %10s\n", "", "iterations", "ns/op");
|
bool need_header = true;
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
for (BenchmarkMapIt it = gBenchmarks.begin(); it != gBenchmarks.end(); ++it) {
|
for (BenchmarkMapIt it = gBenchmarks.begin(); it != gBenchmarks.end(); ++it) {
|
||||||
::testing::Benchmark* b = it->second;
|
::testing::Benchmark* b = it->second;
|
||||||
if (b->ShouldRun(argc, argv)) {
|
if (b->ShouldRun(argc, argv)) {
|
||||||
|
if (need_header) {
|
||||||
|
printf("%-20s %10s %10s\n", "", "iterations", "ns/op");
|
||||||
|
fflush(stdout);
|
||||||
|
need_header = false;
|
||||||
|
}
|
||||||
b->Run();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
62
tests/math_benchmark.cpp
Normal file
62
tests/math_benchmark.cpp
Normal file
|
@ -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);
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
|
// 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();
|
StopBenchmarkTiming();
|
||||||
char* src = new char[nbytes]; char* dst = new char[nbytes];
|
char* src = new char[nbytes]; char* dst = new char[nbytes];
|
||||||
memset(src, 'x', nbytes);
|
memset(src, 'x', nbytes);
|
||||||
|
@ -34,7 +34,7 @@ static void BM_memcmp(int iters, int nbytes) {
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
volatile int c __attribute__((unused)) = 0;
|
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);
|
c += memcmp(dst, src, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,15 @@ static void BM_memcmp(int iters, int nbytes) {
|
||||||
delete[] src;
|
delete[] src;
|
||||||
delete[] dst;
|
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();
|
StopBenchmarkTiming();
|
||||||
char* src = new char[nbytes]; char* dst = new char[nbytes];
|
char* src = new char[nbytes]; char* dst = new char[nbytes];
|
||||||
memset(src, 'x', nbytes);
|
memset(src, 'x', nbytes);
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
for (int i = 0; i < iters; i++) {
|
for (int i = 0; i < iters; ++i) {
|
||||||
memcpy(dst, src, nbytes);
|
memcpy(dst, src, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ static void BM_memcpy(int iters, int nbytes) {
|
||||||
delete[] src;
|
delete[] src;
|
||||||
delete[] dst;
|
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();
|
StopBenchmarkTiming();
|
||||||
char* buf = new char[nbytes + 64];
|
char* buf = new char[nbytes + 64];
|
||||||
memset(buf, 'x', nbytes + 64);
|
memset(buf, 'x', nbytes + 64);
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
for (int i = 0; i < iters; i++) {
|
for (int i = 0; i < iters; ++i) {
|
||||||
memmove(buf, buf + 1, nbytes); // Worst-case overlap.
|
memmove(buf, buf + 1, nbytes); // Worst-case overlap.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,14 +76,14 @@ static void BM_memmove(int iters, int nbytes) {
|
||||||
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
||||||
delete[] buf;
|
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();
|
StopBenchmarkTiming();
|
||||||
char* dst = new char[nbytes];
|
char* dst = new char[nbytes];
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
for (int i = 0; i < iters; i++) {
|
for (int i = 0; i < iters; ++i) {
|
||||||
memset(dst, 0, nbytes);
|
memset(dst, 0, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +91,9 @@ static void BM_memset(int iters, int nbytes) {
|
||||||
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
||||||
delete[] dst;
|
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();
|
StopBenchmarkTiming();
|
||||||
char* s = new char[nbytes];
|
char* s = new char[nbytes];
|
||||||
memset(s, 'x', nbytes);
|
memset(s, 'x', nbytes);
|
||||||
|
@ -101,7 +101,7 @@ static void BM_strlen(int iters, int nbytes) {
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
volatile int c __attribute__((unused)) = 0;
|
volatile int c __attribute__((unused)) = 0;
|
||||||
for (int i = 0; i < iters; i++) {
|
for (int i = 0; i < iters; ++i) {
|
||||||
c += strlen(s);
|
c += strlen(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,4 +109,4 @@ static void BM_strlen(int iters, int nbytes) {
|
||||||
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
|
||||||
delete[] s;
|
delete[] s;
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_strlen)->AT_COMMON_SIZES;
|
BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
|
||||||
|
|
Loading…
Reference in a new issue