diff options
author | joshualitt <joshualitt@chromium.org> | 2015-06-23 07:10:59 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-23 07:10:59 -0700 |
commit | 6205af0e70c3d3f133b716b7e1d14188a2eaf006 (patch) | |
tree | c8383097bf79c8a737457fa486ac05935b357e58 /tools | |
parent | 5351aad9bc5b2e3101472248967e3dc1f84d24ee (diff) |
add autotuning to visualbench
BUG=skia:
Review URL: https://codereview.chromium.org/1201003002
Diffstat (limited to 'tools')
-rw-r--r-- | tools/VisualBench.cpp | 103 | ||||
-rw-r--r-- | tools/VisualBench.h | 9 |
2 files changed, 85 insertions, 27 deletions
diff --git a/tools/VisualBench.cpp b/tools/VisualBench.cpp index 60174a435c..cbc8994592 100644 --- a/tools/VisualBench.cpp +++ b/tools/VisualBench.cpp @@ -24,9 +24,15 @@ __SK_FORCE_IMAGE_DECODER_LINKING; +// Between samples we reset context +// Between frames we swap buffers +// Between flushes we call flush on GrContext + DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag."); -DEFINE_int32(samples, 10, "Number of times to render each skp."); -DEFINE_int32(loops, 5, "Number of times to time."); +DEFINE_int32(samples, 10, "Number of times to time each skp."); +DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample."); +DEFINE_double(flushMs, 20, "Target flush time in millseconds."); +DEFINE_double(loopMs, 5, "Target loop time in millseconds."); DEFINE_int32(msaa, 0, "Number of msaa samples."); DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); @@ -41,10 +47,12 @@ static SkString humanize(double ms) { VisualBench::VisualBench(void* hwnd, int argc, char** argv) : INHERITED(hwnd) - , fLoop(0) , fCurrentPictureIdx(-1) , fCurrentSample(0) - , fState(kPreWarm_State) { + , fCurrentFrame(0) + , fFlushes(1) + , fLoops(1) + , fState(kPreWarmLoops_State) { SkCommandLineFlags::Parse(argc, argv); // read all the skp file names. @@ -66,6 +74,9 @@ VisualBench::VisualBench(void* hwnd, int argc, char** argv) this->setTitle(); this->setupBackend(); + + // Print header + SkDebugf("curr/maxrss\tloops\tflushes\tmin\tmedian\tmean\tmax\tstddev\tbench\n"); } VisualBench::~VisualBench() { @@ -122,8 +133,12 @@ void VisualBench::setupRenderTarget() { } inline void VisualBench::renderFrame(SkCanvas* canvas) { - canvas->drawPicture(fPicture); - canvas->flush(); + for (int flush = 0; flush < fFlushes; flush++) { + for (int loop = 0; loop < fLoops; loop++) { + canvas->drawPicture(fPicture); + } + canvas->flush(); + } INHERITED::present(); } @@ -139,9 +154,11 @@ void VisualBench::printStats() { SkASSERT(measurements.count()); Stats stats(measurements.begin(), measurements.count()); const double stdDevPercent = 100 * sqrt(stats.var) / stats.mean; - SkDebugf("%4d/%-4dMB\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n", + SkDebugf("%4d/%-4dMB\t%d\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n", sk_tools::getCurrResidentSetSizeMB(), sk_tools::getMaxResidentSetSizeMB(), + fLoops, + fFlushes, HUMANIZE(stats.min), HUMANIZE(stats.median), HUMANIZE(stats.mean), @@ -180,6 +197,17 @@ bool VisualBench::loadPicture() { return false; } +void VisualBench::preWarm(State nextState) { + if (fCurrentFrame >= FLAGS_gpuFrameLag) { + // we currently time across all frames to make sure we capture all GPU work + fState = nextState; + fCurrentFrame = 0; + fTimer.start(); + } else { + fCurrentFrame++; + } +} + void VisualBench::draw(SkCanvas* canvas) { if (!this->advanceRecordIfNecessary()) { this->closeWindow(); @@ -187,34 +215,59 @@ void VisualBench::draw(SkCanvas* canvas) { } this->renderFrame(canvas); switch (fState) { - case kPreWarm_State: { - if (fCurrentSample >= FLAGS_gpuFrameLag) { - // TODO we currently time across all frames to make sure we capture all GPU work - // We should also rendering an empty SKP to get a baseline to subtract from - // our timing - fState = kTiming_State; - fCurrentSample -= FLAGS_gpuFrameLag; - fTimer.start(); + case kPreWarmLoops_State: { + this->preWarm(kTuneLoops_State); + break; + } + case kTuneLoops_State: { + if (1 << 30 == fLoops) { + // We're about to wrap. Something's wrong with the bench. + SkDebugf("InnerLoops wrapped\n"); + fLoops = 0; } else { - fCurrentSample++; + fTimer.end(); + double elapsed = fTimer.fWall; + if (elapsed > FLAGS_loopMs) { + fState = kPreWarmTiming_State; + + // Scale back the number of loops + fLoops = (int)ceil(fLoops * FLAGS_loopMs / elapsed); + fFlushes = (int)ceil(FLAGS_flushMs / elapsed); + } else { + fState = kPreWarmLoops_State; + fLoops *= 2; + } + + fCurrentFrame = 0; + fTimer = WallTimer(); + this->resetContext(); } break; } + case kPreWarmTiming_State: { + this->preWarm(kTiming_State); + break; + } case kTiming_State: { - if (fCurrentSample >= FLAGS_samples) { + if (fCurrentFrame >= FLAGS_frames) { fTimer.end(); - fRecords[fCurrentPictureIdx].fMeasurements.push_back(fTimer.fWall / FLAGS_samples); - this->resetContext(); - fTimer = WallTimer(); - fState = kPreWarm_State; - fCurrentSample = 0; - if (fLoop++ > FLAGS_loops) { + fRecords[fCurrentPictureIdx].fMeasurements.push_back( + fTimer.fWall / (FLAGS_frames * fLoops * fFlushes)); + if (fCurrentSample++ >= FLAGS_samples) { + fState = kPreWarmLoops_State; this->printStats(); fPicture.reset(NULL); - fLoop = 0; + fCurrentSample = 0; + fFlushes = 1; + fLoops = 1; + } else { + fState = kPreWarmTiming_State; } + fTimer = WallTimer(); + this->resetContext(); + fCurrentFrame = 0; } else { - fCurrentSample++; + fCurrentFrame++; } break; } diff --git a/tools/VisualBench.h b/tools/VisualBench.h index 9d7b946afe..332fe82eb4 100644 --- a/tools/VisualBench.h +++ b/tools/VisualBench.h @@ -54,14 +54,19 @@ private: }; enum State { - kPreWarm_State, + kPreWarmLoops_State, + kTuneLoops_State, + kPreWarmTiming_State, kTiming_State, }; + void preWarm(State nextState); - int fLoop; int fCurrentPictureIdx; SkAutoTUnref<SkPicture> fPicture; int fCurrentSample; + int fCurrentFrame; + int fFlushes; + int fLoops; SkTArray<Record> fRecords; WallTimer fTimer; State fState; |