# Via Android Git Automerger (1) and others * commit 'd2a6d8d77d1052b2cef7c0296d1396da5d3f7736': Improve benchmarking tool, add a few math benchmarks.
This commit is contained in:
commit
5dc29e97a6
@ -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:
|
||||
|
@ -32,6 +32,8 @@ class Benchmark {
|
||||
|
||||
Benchmark* Arg(int x);
|
||||
|
||||
const char* Name();
|
||||
|
||||
bool ShouldRun(int argc, char* argv[]);
|
||||
void Run();
|
||||
|
||||
|
@ -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,6 +98,9 @@ void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int
|
||||
}
|
||||
|
||||
void Benchmark::Run() {
|
||||
if (fn_ != NULL) {
|
||||
RunWithArg(0);
|
||||
} else {
|
||||
if (args_.empty()) {
|
||||
fprintf(stderr, "%s: no args!\n", name_);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -101,6 +108,7 @@ void Benchmark::Run() {
|
||||
for (size_t i = 0; i < args_.size(); ++i) {
|
||||
RunWithArg(args_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
|
||||
@ -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
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.)
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user