am d2a6d8d7: am c9ab32e4: Merge "Improve benchmarking tool, add a few math benchmarks."

# Via Android Git Automerger (1) and others
* commit 'd2a6d8d77d1052b2cef7c0296d1396da5d3f7736':
  Improve benchmarking tool, add a few math benchmarks.
This commit is contained in:
Elliott Hughes 2013-02-06 19:44:53 -08:00 committed by Android Git Automerger
commit 5dc29e97a6
5 changed files with 112 additions and 25 deletions

View File

@ -26,9 +26,11 @@ benchmark_c_flags = \
-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:

View File

@ -32,6 +32,8 @@ class Benchmark {
Benchmark* Arg(int x);
const char* Name();
bool ShouldRun(int argc, char* argv[]);
void Run();

View File

@ -59,6 +59,10 @@ Benchmark* Benchmark::Arg(int 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.
@ -94,12 +98,16 @@ void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int
}
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 @@ void StartBenchmarkTiming() {
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;
}

62
tests/math_benchmark.cpp Normal file
View 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);

View File

@ -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 @@ static void BM_memcmp(int iters, int nbytes) {
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 @@ static void BM_memcmp(int iters, int nbytes) {
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 @@ static void BM_memcpy(int iters, int nbytes) {
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 @@ static void BM_memmove(int iters, int nbytes) {
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 @@ static void BM_memset(int iters, int nbytes) {
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 @@ static void BM_strlen(int iters, int nbytes) {
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 @@ static void BM_strlen(int iters, int nbytes) {
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
delete[] s;
}
BENCHMARK(BM_strlen)->AT_COMMON_SIZES;
BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;