diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-31 20:00:56 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-31 20:00:56 +0000 |
commit | 55fd612adfd08f5c64fb728bc37a2cb4ae224656 (patch) | |
tree | b49828f094c0bec2e2468f2820449c5df0d9a2d7 /bench | |
parent | 65a629ab33eb829efdfe258e48395d3d43da61ca (diff) |
R=borenet@google.com, bungeman@google.com, robertphillips@google.com, scroggo@google.com, sglez@google.com
Author: bsalomon@google.com
Review URL: https://chromiumcodereview.appspot.com/19862002
git-svn-id: http://skia.googlecode.com/svn/trunk@10473 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'bench')
-rw-r--r-- | bench/TimerData.cpp | 186 | ||||
-rw-r--r-- | bench/TimerData.h | 69 | ||||
-rw-r--r-- | bench/benchmain.cpp | 61 |
3 files changed, 191 insertions, 125 deletions
diff --git a/bench/TimerData.cpp b/bench/TimerData.cpp index 3b4baacfcd..f3084b047a 100644 --- a/bench/TimerData.cpp +++ b/bench/TimerData.cpp @@ -13,96 +13,130 @@ using namespace std; -TimerData::TimerData(const SkString& perIterTimeFormat, const SkString& normalTimeFormat) -: fWallStr(" msecs = ") -, fTruncatedWallStr(" Wmsecs = ") -, fCpuStr(" cmsecs = ") -, fTruncatedCpuStr(" Cmsecs = ") -, fGpuStr(" gmsecs = ") -, fWallSum(0.0) -, fWallMin(numeric_limits<double>::max()) -, fTruncatedWallSum(0.0) -, fTruncatedWallMin(numeric_limits<double>::max()) -, fCpuSum(0.0) -, fCpuMin(numeric_limits<double>::max()) -, fTruncatedCpuSum(0.0) -, fTruncatedCpuMin(numeric_limits<double>::max()) -, fGpuSum(0.0) -, fGpuMin(numeric_limits<double>::max()) -, fPerIterTimeFormat(perIterTimeFormat) -, fNormalTimeFormat(normalTimeFormat) -{} - -static double Min(double a, double b) { - return (a < b) ? a : b; +TimerData::TimerData(int maxNumTimings) +: fMaxNumTimings(maxNumTimings) +, fCurrTiming(0) +, fWallTimes(maxNumTimings) +, fTruncatedWallTimes(maxNumTimings) +, fCpuTimes(maxNumTimings) +, fTruncatedCpuTimes(maxNumTimings) +, fGpuTimes(maxNumTimings){ } -void TimerData::appendTimes(BenchTimer* timer, bool last) { +bool TimerData::appendTimes(BenchTimer* timer) { SkASSERT(timer != NULL); - SkString formatString(fPerIterTimeFormat); - if (!last) { - formatString.append(","); + if (fCurrTiming >= fMaxNumTimings) { + return false; } - const char* format = formatString.c_str(); - fWallStr.appendf(format, timer->fWall); - fCpuStr.appendf(format, timer->fCpu); - fTruncatedWallStr.appendf(format, timer->fTruncatedWall); - fTruncatedCpuStr.appendf(format, timer->fTruncatedCpu); - fGpuStr.appendf(format, timer->fGpu); - - // Store the minimum values. We do not need to special case the first time since we initialized - // to max double. - fWallMin = Min(fWallMin, timer->fWall); - fCpuMin = Min(fCpuMin, timer->fCpu); - fTruncatedWallMin = Min(fTruncatedWallMin, timer->fTruncatedWall); - fTruncatedCpuMin = Min(fTruncatedCpuMin, timer->fTruncatedCpu); - fGpuMin = Min(fGpuMin, timer->fGpu); - - // Tally the sum of each timer type. - fWallSum += timer->fWall; - fCpuSum += timer->fCpu; - fTruncatedWallSum += timer->fTruncatedWall; - fTruncatedCpuSum += timer->fTruncatedCpu; - fGpuSum += timer->fGpu; + fWallTimes[fCurrTiming] = timer->fWall; + fTruncatedWallTimes[fCurrTiming] = timer->fTruncatedWall; + fCpuTimes[fCurrTiming] = timer->fCpu; + fTruncatedCpuTimes[fCurrTiming] = timer->fTruncatedCpu; + fGpuTimes[fCurrTiming] = timer->fGpu; + + ++fCurrTiming; + + return true; } -SkString TimerData::getResult(bool logPerIter, bool printMin, int repeatDraw, - const char *configName, bool showWallTime, bool showTruncatedWallTime, - bool showCpuTime, bool showTruncatedCpuTime, bool showGpuTime) { - // output each repeat (no average) if logPerIter is set, - // otherwise output only the average - if (!logPerIter) { - const char* format = fNormalTimeFormat.c_str(); - fWallStr.set(" msecs = "); - fWallStr.appendf(format, printMin ? fWallMin : fWallSum / repeatDraw); - fCpuStr.set(" cmsecs = "); - fCpuStr.appendf(format, printMin ? fCpuMin : fCpuSum / repeatDraw); - fTruncatedWallStr.set(" Wmsecs = "); - fTruncatedWallStr.appendf(format, - printMin ? fTruncatedWallMin : fTruncatedWallSum / repeatDraw); - fTruncatedCpuStr.set(" Cmsecs = "); - fTruncatedCpuStr.appendf(format, - printMin ? fTruncatedCpuMin : fTruncatedCpuSum / repeatDraw); - fGpuStr.set(" gmsecs = "); - fGpuStr.appendf(format, printMin ? fGpuMin : fGpuSum / repeatDraw); +SkString TimerData::getResult(const char* doubleFormat, + Result result, + const char *configName, + uint32_t timerFlags, + int itersPerTiming) { + SkASSERT(itersPerTiming >= 1); + + if (!fCurrTiming) { + return SkString(""); + } + + int numTimings = fCurrTiming; + + SkString wallStr(" msecs = "); + SkString truncWallStr(" Wmsecs = "); + SkString cpuStr(" cmsecs = "); + SkString truncCpuStr(" Cmsecs = "); + SkString gpuStr(" gmsecs = "); + + double wallMin = std::numeric_limits<double>::max(); + double truncWallMin = std::numeric_limits<double>::max(); + double cpuMin = std::numeric_limits<double>::max(); + double truncCpuMin = std::numeric_limits<double>::max(); + double gpuMin = std::numeric_limits<double>::max(); + + double wallSum = 0; + double truncWallSum = 0; + double cpuSum = 0; + double truncCpuSum = 0; + double gpuSum = 0; + + for (int i = 0; i < numTimings; ++i) { + if (kPerIter_Result == result) { + wallStr.appendf(doubleFormat, fWallTimes[i]); + truncWallStr.appendf(doubleFormat, fTruncatedWallTimes[i]); + cpuStr.appendf(doubleFormat, fCpuTimes[i]); + truncCpuStr.appendf(doubleFormat, fTruncatedCpuTimes[i]); + gpuStr.appendf(doubleFormat, fGpuTimes[i]); + + if (i != numTimings - 1) { + static const char kSep[] = ", "; + wallStr.append(kSep); + truncWallStr.append(kSep); + cpuStr.append(kSep); + truncCpuStr.append(kSep); + gpuStr.append(kSep); + } + } else if (kMin_Result == result) { + wallMin = SkTMin(wallMin, fWallTimes[i]); + truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]); + cpuMin = SkTMin(cpuMin, fCpuTimes[i]); + truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]); + gpuMin = SkTMin(gpuMin, fGpuTimes[i]); + } else { + SkASSERT(kAvg_Result == result); + wallSum += fWallTimes[i]; + truncWallSum += fTruncatedWallTimes[i]; + cpuSum += fCpuTimes[i]; + truncCpuSum += fTruncatedCpuTimes[i]; + } + + // We always track the GPU sum because whether it is non-zero indicates if valid gpu times + // were recorded at all. + gpuSum += fGpuTimes[i]; } + + if (kMin_Result == result) { + wallStr.appendf(doubleFormat, wallMin / itersPerTiming); + truncWallStr.appendf(doubleFormat, truncWallMin / itersPerTiming); + cpuStr.appendf(doubleFormat, cpuMin / itersPerTiming); + truncCpuStr.appendf(doubleFormat, truncCpuMin / itersPerTiming); + gpuStr.appendf(doubleFormat, gpuMin / itersPerTiming); + } else if (kAvg_Result == result) { + int divisor = numTimings * itersPerTiming; + wallStr.appendf(doubleFormat, wallSum / divisor); + truncWallStr.appendf(doubleFormat, truncWallSum / divisor); + cpuStr.appendf(doubleFormat, cpuSum / divisor); + truncCpuStr.appendf(doubleFormat, truncCpuSum / divisor); + gpuStr.appendf(doubleFormat, gpuSum / divisor); + } + SkString str; str.printf(" %4s:", configName); - if (showWallTime) { - str += fWallStr; + if (timerFlags & kWall_Flag) { + str += wallStr; } - if (showTruncatedWallTime) { - str += fTruncatedWallStr; + if (timerFlags & kTruncatedWall_Flag) { + str += truncWallStr; } - if (showCpuTime) { - str += fCpuStr; + if (timerFlags & kCpu_Flag) { + str += cpuStr; } - if (showTruncatedCpuTime) { - str += fTruncatedCpuStr; + if (timerFlags & kTruncatedCpu_Flag) { + str += truncCpuStr; } - if (showGpuTime && fGpuSum > 0) { - str += fGpuStr; + if ((timerFlags & kGpu_Flag) && gpuSum > 0) { + str += gpuStr; } return str; } diff --git a/bench/TimerData.h b/bench/TimerData.h index d97a0632aa..ed0ee473c1 100644 --- a/bench/TimerData.h +++ b/bench/TimerData.h @@ -10,37 +10,64 @@ #define TimerData_DEFINED #include "SkString.h" +#include "SkTemplates.h" + class BenchTimer; class TimerData { public: - TimerData(const SkString& perIterTimeFormat, const SkString& normalTimeFormat); + /** + * Constructs a TimerData to hold at most maxNumTimings sets of elapsed timer values. + **/ + explicit TimerData(int maxNumTimings); /** - * Append the value from each timer in BenchTimer to our various strings, and update the - * minimum and sum times. + * Collect times from the BenchTimer for an iteration. It will fail if called more often than + * indicated in the constructor. + * * @param BenchTimer Must not be null. - * @param last True if this is the last set of times to add. */ - void appendTimes(BenchTimer*, bool last); - SkString getResult(bool logPerIter, bool printMin, int repeatDraw, const char* configName, - bool showWallTime, bool showTruncatedWallTime, bool showCpuTime, - bool showTruncatedCpuTime, bool showGpuTime); + bool appendTimes(BenchTimer*); + + enum Result { + kMin_Result, + kAvg_Result, + kPerIter_Result + }; + + enum TimerFlags { + kWall_Flag = 0x1, + kTruncatedWall_Flag = 0x2, + kCpu_Flag = 0x4, + kTruncatedCpu_Flag = 0x8, + kGpu_Flag = 0x10 + }; + + /** + * Gets the timer data results as a string. + * @param doubleFormat printf-style format for doubles (e.g. "%02d") + * @param result the type of result desired + * @param the name of the config being timed (prepended to results string) + * @param timerFlags bitfield of TimerFlags values indicating which timers should be reported. + * @param itersPerTiming the number of test/bench iterations that correspond to each + * appendTimes() call, 1 when appendTimes is called for each iteration. + */ + SkString getResult(const char* doubleFormat, + Result result, + const char* configName, + uint32_t timerFlags, + int itersPerTiming = 1); + private: - SkString fWallStr; - SkString fTruncatedWallStr; - SkString fCpuStr; - SkString fTruncatedCpuStr; - SkString fGpuStr; - double fWallSum, fWallMin; - double fTruncatedWallSum, fTruncatedWallMin; - double fCpuSum, fCpuMin; - double fTruncatedCpuSum, fTruncatedCpuMin; - double fGpuSum, fGpuMin; - - SkString fPerIterTimeFormat; - SkString fNormalTimeFormat; + int fMaxNumTimings; + int fCurrTiming; + + SkAutoTArray<double> fWallTimes; + SkAutoTArray<double> fTruncatedWallTimes; + SkAutoTArray<double> fCpuTimes; + SkAutoTArray<double> fTruncatedCpuTimes; + SkAutoTArray<double> fGpuTimes; }; #endif // TimerData_DEFINED diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index 1ace7d108a..22487537eb 100644 --- a/bench/benchmain.cpp +++ b/bench/benchmain.cpp @@ -348,20 +348,20 @@ int tool_main(int argc, char** argv) { SkTDict<const char*> defineDict(1024); int repeatDraw = 1; - bool logPerIter = false; + int forceAlpha = 0xFF; bool forceAA = true; bool forceFilter = false; SkTriState::State forceDither = SkTriState::kDefault; - bool timerWall = false; - bool truncatedTimerWall = false; - bool timerCpu = true; - bool truncatedTimerCpu = false; - bool timerGpu = true; + + static const uint32_t kDefaultTimerTypes = TimerData::kCpu_Flag | TimerData::kGpu_Flag; + static const TimerData::Result kDefaultTimerResult = TimerData::kAvg_Result; + uint32_t timerTypes = kDefaultTimerTypes; + TimerData::Result timerResult = kDefaultTimerResult; + bool doScale = false; bool doRotate = false; bool doClip = false; - bool printMin = false; bool hasStrokeWidth = false; #if SK_SUPPORT_GPU @@ -410,22 +410,18 @@ int tool_main(int argc, char** argv) { return -1; } } else if (strcmp(*argv, "--logPerIter") == 0) { - logPerIter = true; + timerResult = TimerData::kPerIter_Result; } else if (strcmp(*argv, "--timers") == 0) { argv++; if (argv < stop) { - timerWall = false; - truncatedTimerWall = false; - timerCpu = false; - truncatedTimerCpu = false; - timerGpu = false; + timerTypes = 0; for (char* t = *argv; *t; ++t) { switch (*t) { - case 'w': timerWall = true; break; - case 'c': timerCpu = true; break; - case 'W': truncatedTimerWall = true; break; - case 'C': truncatedTimerCpu = true; break; - case 'g': timerGpu = true; break; + case 'w': timerTypes |= TimerData::kWall_Flag; break; + case 'c': timerTypes |= TimerData::kCpu_Flag; break; + case 'W': timerTypes |= TimerData::kTruncatedWall_Flag; break; + case 'C': timerTypes |= TimerData::kTruncatedCpu_Flag; break; + case 'g': timerTypes |= TimerData::kGpu_Flag; break; } } } else { @@ -440,7 +436,7 @@ int tool_main(int argc, char** argv) { } else if (!strcmp(*argv, "--clip")) { doClip = true; } else if (!strcmp(*argv, "--min")) { - printMin = true; + timerResult = TimerData::kMin_Result; } else if (strcmp(*argv, "--forceAA") == 0) { if (!parse_bool_arg(++argv, stop, &forceAA)) { logger.logError("missing arg for --forceAA\n"); @@ -648,9 +644,9 @@ int tool_main(int argc, char** argv) { str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d " "deferred=%s logperiter=%d", forceAlpha, forceAA, forceFilter, deferredMode, - logPerIter); + TimerData::kPerIter_Result == timerResult); str.appendf(" rotate=%d scale=%d clip=%d min=%d", - doRotate, doScale, doClip, printMin); + doRotate, doScale, doClip, TimerData::kMin_Result == timerResult); str.appendf(" record=%d picturerecord=%d", benchMode == kRecord_benchModes, benchMode == kPictureRecord_benchModes); @@ -883,7 +879,7 @@ int tool_main(int argc, char** argv) { } // record timer values for each repeat, and their sum - TimerData timerData(perIterTimeformat, normalTimeFormat); + TimerData timerData(repeatDraw); for (int i = 0; i < repeatDraw; i++) { if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) { // This will clear the recorded commands so that they do not @@ -925,15 +921,24 @@ int tool_main(int argc, char** argv) { // have completed timer->end(); - timerData.appendTimes(timer, repeatDraw - 1 == i); + SkAssertResult(timerData.appendTimes(timer)); } if (repeatDraw > 1) { - SkString result = timerData.getResult( - logPerIter, printMin, repeatDraw, configName, - timerWall, truncatedTimerWall, timerCpu, - truncatedTimerCpu, - timerGpu && NULL != context); + const char* timeFormat; + if (TimerData::kPerIter_Result == timerResult) { + timeFormat = perIterTimeformat.c_str(); + } else { + timeFormat = normalTimeFormat.c_str(); + } + uint32_t filteredTimerTypes = timerTypes; + if (NULL == context) { + filteredTimerTypes &= ~TimerData::kGpu_Flag; + } + SkString result = timerData.getResult(timeFormat, + timerResult, + configName, + filteredTimerTypes); logger.logProgress(result); } if (outDir.size() > 0 && kNonRendering_Backend != backend) { |