00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _BENCHMARK_H
00034 #define _BENCHMARK_H
00035 #pragma once
00036
00037 #include "BenchFormatter.h"
00038 #include "BenchResult.h"
00039 #include "Stopwatch.h"
00040
00041 #include <iomanip>
00042 #include <iostream>
00043 #include <sstream>
00044 #include <string>
00045 #include <vector>
00046
00047 #include <float.h>
00048 #include <math.h>
00049
00055 template<typename S>
00056 class Benchmark
00057 {
00058 public:
00059 Benchmark(): mName("") {}
00060 Benchmark(std::string n): mName(n) {}
00061 virtual ~Benchmark() {}
00062
00071 void setValue(S val) { mVal = val; }
00072
00081 S getValue() const { return mVal; }
00082
00092 virtual void preBench() {}
00093
00094
00099 virtual void bench() = 0;
00100
00108 virtual void postBench() {}
00109
00115 std::string getName() const { return mName; }
00116
00121 void setName(std::string n) { mName = n; }
00122
00123
00138 BenchResult run(unsigned repeats, unsigned warmup);
00139 private:
00140 std::string mName;
00141 S mVal;
00142 };
00143
00150 template<typename S>
00151 class BenchGroup
00152 {
00153 public:
00154 BenchGroup() : mMaxRuntime(DBL_MAX), mRepeats(5), mWarmup(0) {}
00155 ~BenchGroup();
00156
00168 void addBench(Benchmark<S> *bench) { mBenches.push_back(bench); }
00169 void addVal(const S val) { mVals.push_back(val); }
00170
00182 void setMaxRuntime(const double d) { mMaxRuntime = d; }
00183 double getMaxRuntime() const { return mMaxRuntime; }
00184
00189 void setRepeats(const unsigned i) { mRepeats = i; }
00190 unsigned getRepeats() const { return mRepeats; }
00191
00198 void setWarmup(const unsigned i) { mWarmup = i; }
00199 unsigned getWarmup() const { return mWarmup; }
00200
00209 void run(BenchFormatter& formatter) const;
00210
00211 protected:
00212 double mMaxRuntime;
00213 unsigned mRepeats;
00214 unsigned mWarmup;
00215
00216 std::vector<Benchmark<S> *> mBenches;
00217 std::vector<S> mVals;
00218 };
00219
00220 template<typename S>
00221 BenchResult Benchmark<S>::run(unsigned repeats, unsigned warmup)
00222 {
00223 for (unsigned i = 0; i < warmup; i++)
00224 {
00225 preBench();
00226 bench();
00227 postBench();
00228 }
00229
00230 Stopwatch timer;
00231 std::vector<Stopwatch::Time> times;
00232 for (unsigned i = 0; i < repeats; i++)
00233 {
00234 preBench();
00235
00236 timer.start();
00237 bench();
00238 timer.stop();
00239
00240 postBench();
00241
00242 times.push_back(timer.getTime());
00243 timer.reset();
00244 }
00245
00246 BenchResult result(times);
00247 result.setName(getName());
00248
00249 std::stringstream tmp;
00250 tmp.precision(15);
00251 tmp << mVal;
00252 result.setValue(tmp.str());
00253
00254 return result;
00255 }
00256
00257 template<typename S>
00258 BenchGroup<S>::~BenchGroup()
00259 {
00260 for (size_t i = 0; i < mBenches.size(); i++)
00261 {
00262 delete mBenches[i];
00263 }
00264 }
00265
00266 template<typename S>
00267 void BenchGroup<S>::run(BenchFormatter& formatter) const
00268 {
00269 std::vector<bool> runBench;
00270
00271 std::vector<std::string> values;
00272 std::vector<std::string> titles;
00273 for (size_t i = 0; i < mBenches.size(); i++)
00274 {
00275 titles.push_back(mBenches[i]->getName());
00276 runBench.push_back(true);
00277 }
00278
00279 for (size_t i = 0; i < mVals.size(); i++)
00280 {
00281 std::stringstream valString;
00282 valString << mVals[i];
00283 values.push_back(valString.str());
00284 }
00285 formatter.writeTitle(titles, values);
00286
00287 try
00288 {
00289 for (size_t i = 0; i < mVals.size(); i++)
00290 {
00291 std::stringstream valString;
00292 valString << mVals[i];
00293
00294 std::vector<BenchResult> results;
00295
00296 for (size_t j = 0; j < mBenches.size(); j++)
00297 {
00298 if (runBench[j])
00299 {
00300 mBenches[j]->setValue(mVals[i]);
00301 results.push_back(mBenches[j]->run(mRepeats, mWarmup));
00302
00303 if (results.back().getTimeValue(TimeType::WALL_CLOCK, TimeValue::AVERAGE) > mMaxRuntime)
00304 {
00305 runBench[j] = false;
00306 }
00307 }
00308 }
00309 formatter.writeResult(valString.str(), results);
00310 }
00311 }
00312 catch(...)
00313 {
00314
00315 }
00316 formatter.finish();
00317 }
00318
00319 #endif