提交 11186577 编写于 作者: W wuchenghui

add test benchmark

上级 87134853
bazel-* bazel-*
.idea/
cmake-build-debug/
...@@ -5,16 +5,36 @@ package( ...@@ -5,16 +5,36 @@ package(
default_visibility = ["//visibility:public"], default_visibility = ["//visibility:public"],
) )
licenses(["notice"]) # Apache 2.0 licenses(["notice"]) # Apache 2.0
cc_library( cc_library(
name = "core", name = "core",
srcs = glob(["*.cc"]), srcs = glob([
hdrs = glob(["*.h"]), "*.cc",
]),
hdrs = glob([
"*.h",
]),
copts = ["-std=c++11"],
deps = [ deps = [
"//mace/proto:cc_proto", "//mace/proto:cc_proto",
], ],
copts = ['-std=c++11'],
) )
# Main program for tests
cc_library(
name = "test_main",
testonly = 1,
srcs = glob([
"testing/*.cc",
]),
hdrs = glob([
"testing/*.h",
]),
copts = ["-std=c++11"],
linkopts = ["-lm"],
deps = [
":core",
],
alwayslink = 1,
)
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
#ifndef MACE_CORE_MACROS_H_
#define MACE_CORE_MACROS_H_
// GCC can be told that a certain branch is not likely to be taken (for
// instance, a CHECK failure), and use that information in static analysis.
// Giving it this information can help it optimize for the common case in
// the absence of better information (ie. -fprofile-arcs).
#if defined(COMPILER_GCC3)
#define MACE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
#define MACE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#else
#define MACE_PREDICT_FALSE(x) (x)
#define MACE_PREDICT_TRUE(x) (x)
#endif
#endif //MACE_CORE_MACROS_H_
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
// Only support POSIX environment
#ifndef MACE_TESTING_TIME_H_
#define MACE_TESTING_TIME_H_
#include <stdint.h>
#include <sys/time.h>
#include <time.h>
#include "mace/core/types.h"
namespace mace {
namespace testing {
inline int64 NowMicros() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
}
} // namespace testing
} // namespace mace
#endif // MACE_TESTING_TIME_H_
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
#include "mace/core/testing/test_benchmark.h"
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include "mace/core/logging.h"
#include "mace/core/testing/env_time.h"
namespace mace {
namespace testing {
static std::vector<Benchmark*>* all_benchmarks = nullptr;
static std::string label;
static int64 bytes_processed;
static int64 items_processed;
static int64 accum_time = 0;
static int64 start_time = 0;
Benchmark::Benchmark(const char* name, void (*fn)(int))
: name_(name), num_args_(0), fn0_(fn) {
args_.push_back(std::make_pair(-1, -1));
Register();
}
Benchmark::Benchmark(const char* name, void (*fn)(int, int))
: name_(name), num_args_(1), fn1_(fn) {
Register();
}
Benchmark::Benchmark(const char* name, void (*fn)(int, int, int))
: name_(name), num_args_(2), fn2_(fn) {
Register();
}
// Run all benchmarks
void Benchmark::Run() {
if (!all_benchmarks) return;
// Compute name width.
int width = 10;
string name;
for (auto b : *all_benchmarks) {
name = b->name_;
for (auto arg : b->args_) {
name.resize(b->name_.size());
if (arg.first >= 0) {
name += "/" + arg.first;
if (arg.second >= 0) {
name += "/" + arg.second;
}
}
width = std::max<int>(width, name.size());
}
}
printf("%-*s %10s %10s\n", width, "Benchmark", "Time(ns)", "Iterations");
printf("%s\n", string(width + 22, '-').c_str());
for (auto b : *all_benchmarks) {
name = b->name_;
for (auto arg : b->args_) {
name.resize(b->name_.size());
if (arg.first >= 0) {
name += "/" + arg.first;
if (arg.second >= 0) {
name += "/" + arg.second;
}
}
int iters;
double seconds;
b->Run(arg.first, arg.second, &iters, &seconds);
char buf[100];
std::string full_label = label;
if (bytes_processed > 0) {
snprintf(buf, sizeof(buf), " %.1fMB/s",
(bytes_processed * 1e-6) / seconds);
full_label += buf;
}
if (items_processed > 0) {
snprintf(buf, sizeof(buf), " %.1fM items/s",
(items_processed * 1e-6) / seconds);
full_label += buf;
}
printf("%-*s %10.0f %10d\t%s\n", width, name.c_str(),
seconds * 1e9 / iters, iters, full_label.c_str());
}
}
}
void Benchmark::Register() {
if (!all_benchmarks) all_benchmarks = new std::vector<Benchmark*>;
all_benchmarks->push_back(this);
}
void Benchmark::Run(int arg1, int arg2, int* run_count, double* run_seconds) {
static const int64 kMinIters = 100;
static const int64 kMaxIters = 1000000000;
static const double kMinTime = 0.5;
int64 iters = kMinIters;
while (true) {
accum_time = 0;
start_time = NowMicros();
bytes_processed = -1;
items_processed = -1;
label.clear();
if (fn0_) {
(*fn0_)(iters);
} else if (fn1_) {
(*fn1_)(iters, arg1);
} else {
(*fn2_)(iters, arg1, arg2);
}
StopTiming();
const double seconds = accum_time * 1e-6;
if (seconds >= kMinTime || iters >= kMaxIters) {
*run_count = iters;
*run_seconds = seconds;
return;
}
// Update number of iterations. Overshoot by 40% in an attempt
// to succeed the next time.
double multiplier = 1.4 * kMinTime / std::max(seconds, 1e-9);
multiplier = std::min(10.0, multiplier);
if (multiplier <= 1.0) multiplier *= 2.0;
iters = std::max<int64>(multiplier * iters, iters + 1);
iters = std::min(iters, kMaxIters);
}
}
void BytesProcessed(int64 n) { bytes_processed = n; }
void ItemsProcessed(int64 n) { items_processed = n; }
void StartTiming() {
if (start_time == 0) start_time = NowMicros();
}
void StopTiming() {
if (start_time != 0) {
accum_time += (NowMicros() - start_time);
start_time = 0;
}
}
} // namespace testing
} // namespace mace
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
// Simple benchmarking facility.
#ifndef MACE_TEST_BENCHMARK_H_
#define MACE_TEST_BENCHMARK_H_
#include <utility>
#include <vector>
#include "mace/core/types.h"
#define MACE_BENCHMARK_CONCAT(a, b, c) a##b##c
#define BENCHMARK(n) \
static ::mace::testing::Benchmark* MACE_BENCHMARK_CONCAT(__benchmark_, n, __LINE__) = \
(new ::mace::testing::Benchmark(#n, (n)))
namespace mace {
namespace testing {
class Benchmark {
public:
Benchmark(const char* name, void (*fn)(int));
Benchmark(const char* name, void (*fn)(int, int));
Benchmark(const char* name, void (*fn)(int, int, int));
static void Run();
private:
string name_;
int num_args_;
std::vector<std::pair<int, int>> args_;
void (*fn0_)(int) = nullptr;
void (*fn1_)(int, int) = nullptr;
void (*fn2_)(int, int, int) = nullptr;
void Register();
void Run(int arg1, int arg2, int* run_count, double* run_seconds);
};
void RunBenchmarks();
void SetLabel(const std::string& label);
void BytesProcessed(int64);
void ItemsProcessed(int64);
void StartTiming();
void StopTiming();
void UseRealTime();
} // namespace testing
} // namespace mace
#endif // MACE_TEST_BENCHMARK_H_
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
#include <iostream>
#include "mace/core/testing/test_benchmark.h"
int main(int argc, char** argv) {
std::cout << "Running main() from test_main.cc\n";
mace::testing::Benchmark::Run();
return 0;
}
...@@ -51,6 +51,8 @@ MATCH_TYPE_AND_ENUM(string, DT_STRING); ...@@ -51,6 +51,8 @@ MATCH_TYPE_AND_ENUM(string, DT_STRING);
MATCH_TYPE_AND_ENUM(int64, DT_INT64); MATCH_TYPE_AND_ENUM(int64, DT_INT64);
MATCH_TYPE_AND_ENUM(bool, DT_BOOL); MATCH_TYPE_AND_ENUM(bool, DT_BOOL);
static const int32 kint32max = ((int32)0x7FFFFFFF);
} // namespace mace } // namespace mace
#endif // MACE_CORE_TYPES_H_ #endif // MACE_CORE_TYPES_H_
...@@ -5,10 +5,29 @@ cc_binary( ...@@ -5,10 +5,29 @@ cc_binary(
name = "helloworld", name = "helloworld",
srcs = [ srcs = [
"helloworld.cc", "helloworld.cc",
], ],
copts = ["-std=c++11"],
linkopts = if_android([
"-pie",
"-llog",
]),
deps = [ deps = [
"//mace/ops:ops", "//mace/core",
], "//mace/ops",
copts = ['-std=c++11'], ],
linkopts = if_android(["-pie", "-llog"]), )
cc_test(
name = "benchmark_example",
srcs = ["benchmark_example.cc"],
copts = ["-std=c++11"],
linkopts = if_android([
"-pie",
"-llog",
]),
linkstatic = 1,
deps = [
"//mace/core",
"//mace/core:test_main",
],
) )
...@@ -21,9 +21,9 @@ docker run -it --net=host mace-dev /bin/bash ...@@ -21,9 +21,9 @@ docker run -it --net=host mace-dev /bin/bash
* Push and run the example * Push and run the example
``` ```
adb shell "mkdir /data/local/tmp/helloword" adb shell "mkdir /data/local/tmp"
adb shell push bazel-bin/mace/examples/helloworld /data/local/tmp/helloword adb push bazel-bin/mace/examples/helloworld /data/local/tmp/
adb shell /data/local/tmp/helloword/helloworld adb shell /data/local/tmp/helloworld
``` ```
* Check the logs * Check the logs
......
#include "mace/core/testing/test_benchmark.h"
static void foo(int iters) {
static const int N = 32;
const int64 tot = static_cast<int64>(iters) * N;
mace::testing::ItemsProcessed(tot);
mace::testing::BytesProcessed(tot * (sizeof(float)));
float* inp = new float[N];
float* out = new float[N];
while (iters--) {
for (int i=0; i < N; i++) {
out[i] = inp[i] * 2.0;
}
}
delete[] inp;
delete[] out;
}
BENCHMARK(foo);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册