| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2014 Google Inc. | 2  * Copyright 2014 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include <ctype.h> | 8 #include <ctype.h> | 
| 9 | 9 | 
| 10 #include "Benchmark.h" | 10 #include "Benchmark.h" | 
| 11 #include "CrashHandler.h" | 11 #include "CrashHandler.h" | 
| 12 #include "ResultsWriter.h" | 12 #include "ResultsWriter.h" | 
| 13 #include "Stats.h" | 13 #include "Stats.h" | 
| 14 #include "Timer.h" | 14 #include "Timer.h" | 
| 15 | 15 | 
| 16 #include "SkCanvas.h" | 16 #include "SkCanvas.h" | 
| 17 #include "SkCommandLineFlags.h" | 17 #include "SkCommandLineFlags.h" | 
| 18 #include "SkForceLinking.h" | 18 #include "SkForceLinking.h" | 
| 19 #include "SkGraphics.h" | 19 #include "SkGraphics.h" | 
| 20 #include "SkString.h" | 20 #include "SkString.h" | 
| 21 #include "SkSurface.h" | 21 #include "SkSurface.h" | 
| 22 | 22 | 
| 23 #if SK_SUPPORT_GPU | 23 #if SK_SUPPORT_GPU | 
| 24     #include "GrContextFactory.h" | 24     #include "GrContextFactory.h" | 
| 25     GrContextFactory gGrFactory; | 25     GrContextFactory gGrFactory; | 
| 26 #endif | 26 #endif | 
| 27 | 27 | 
| 28 __SK_FORCE_IMAGE_DECODER_LINKING; | 28 __SK_FORCE_IMAGE_DECODER_LINKING; | 
| 29 | 29 | 
|  | 30 #if SK_DEBUG | 
|  | 31     DEFINE_bool(runOnce, true, "Run each benchmark just once?"); | 
|  | 32 #else | 
|  | 33     DEFINE_bool(runOnce, false, "Run each benchmark just once?"); | 
|  | 34 #endif | 
|  | 35 | 
| 30 DEFINE_int32(samples, 10, "Number of samples to measure for each bench."); | 36 DEFINE_int32(samples, 10, "Number of samples to measure for each bench."); | 
| 31 DEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); | 37 DEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); | 
| 32 DEFINE_double(overheadGoal, 0.0001, | 38 DEFINE_double(overheadGoal, 0.0001, | 
| 33               "Loop until timer overhead is at most this fraction of our measurm
     ents."); | 39               "Loop until timer overhead is at most this fraction of our measurm
     ents."); | 
| 34 DEFINE_string(match, "", "The usual filters on file names of benchmarks to measu
     re."); | 40 DEFINE_string(match, "", "The usual filters on file names of benchmarks to measu
     re."); | 
| 35 DEFINE_bool2(quiet, q, false, "Print only bench name and minimum sample."); | 41 DEFINE_bool2(quiet, q, false, "Print only bench name and minimum sample."); | 
| 36 DEFINE_bool2(verbose, v, false, "Print all samples."); | 42 DEFINE_bool2(verbose, v, false, "Print all samples."); | 
| 37 DEFINE_string(config, "nonrendering 8888 gpu", "Configs to measure. Options: " | 43 DEFINE_string(config, "nonrendering 8888 gpu", "Configs to measure. Options: " | 
| 38               "565 8888 gpu nonrendering debug nullgpu msaa4 msaa16 nvprmsaa4 nv
     prmsaa16 angle"); | 44               "565 8888 gpu nonrendering debug nullgpu msaa4 msaa16 nvprmsaa4 nv
     prmsaa16 angle"); | 
| 39 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); | 45 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 97     // | 103     // | 
| 98     // Doing some math, we get: | 104     // Doing some math, we get: | 
| 99     // | 105     // | 
| 100     //  (overhead / FLAGS_overheadGoal) - overhead | 106     //  (overhead / FLAGS_overheadGoal) - overhead | 
| 101     //  ------------------------------------------  < N | 107     //  ------------------------------------------  < N | 
| 102     //       bench_plus_overhead - overhead) | 108     //       bench_plus_overhead - overhead) | 
| 103     // | 109     // | 
| 104     // Luckily, this also works well in practice. :) | 110     // Luckily, this also works well in practice. :) | 
| 105     const double numer = overhead / FLAGS_overheadGoal - overhead; | 111     const double numer = overhead / FLAGS_overheadGoal - overhead; | 
| 106     const double denom = bench_plus_overhead - overhead; | 112     const double denom = bench_plus_overhead - overhead; | 
| 107     const int loops = (int)ceil(numer / denom); | 113     const int loops = FLAGS_runOnce ? 1 : (int)ceil(numer / denom); | 
| 108 | 114 | 
| 109     for (int i = 0; i < FLAGS_samples; i++) { | 115     for (int i = 0; i < FLAGS_samples; i++) { | 
| 110         samples[i] = time(loops, bench, canvas, NULL) / loops; | 116         samples[i] = time(loops, bench, canvas, NULL) / loops; | 
| 111     } | 117     } | 
| 112     return loops; | 118     return loops; | 
| 113 } | 119 } | 
| 114 | 120 | 
| 115 #if SK_SUPPORT_GPU | 121 #if SK_SUPPORT_GPU | 
| 116 static int gpu_bench(SkGLContextHelper* gl, | 122 static int gpu_bench(SkGLContextHelper* gl, | 
| 117                      Benchmark* bench, | 123                      Benchmark* bench, | 
| 118                      SkCanvas* canvas, | 124                      SkCanvas* canvas, | 
| 119                      double* samples) { | 125                      double* samples) { | 
| 120     // Make sure we're done with whatever came before. | 126     // Make sure we're done with whatever came before. | 
| 121     SK_GL(*gl, Finish()); | 127     SK_GL(*gl, Finish()); | 
| 122 | 128 | 
| 123     // First, figure out how many loops it'll take to get a frame up to FLAGS_gp
     uMs. | 129     // First, figure out how many loops it'll take to get a frame up to FLAGS_gp
     uMs. | 
| 124     int loops = 1; | 130     int loops = 1; | 
| 125     double elapsed = 0; | 131     if (!FLAGS_runOnce) { | 
| 126     do { | 132         double elapsed = 0; | 
| 127         loops *= 2; | 133         do { | 
| 128         // If the GPU lets frames lag at all, we need to make sure we're timing | 134             loops *= 2; | 
| 129         // _this_ round, not still timing last round.  We force this by looping | 135             // If the GPU lets frames lag at all, we need to make sure we're tim
     ing | 
| 130         // more times than any reasonable GPU will allow frames to lag. | 136             // _this_ round, not still timing last round.  We force this by loop
     ing | 
| 131         for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 137             // more times than any reasonable GPU will allow frames to lag. | 
| 132             elapsed = time(loops, bench, canvas, gl); | 138             for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 
| 133         } | 139                 elapsed = time(loops, bench, canvas, gl); | 
| 134     } while (elapsed < FLAGS_gpuMs); | 140             } | 
|  | 141         } while (elapsed < FLAGS_gpuMs); | 
| 135 | 142 | 
| 136     // We've overshot at least a little.  Scale back linearly. | 143         // We've overshot at least a little.  Scale back linearly. | 
| 137     loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); | 144         loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); | 
| 138 | 145 | 
| 139     // Might as well make sure we're not still timing our calibration. | 146         // Might as well make sure we're not still timing our calibration. | 
| 140     SK_GL(*gl, Finish()); | 147         SK_GL(*gl, Finish()); | 
|  | 148     } | 
| 141 | 149 | 
| 142     // Pretty much the same deal as the calibration: do some warmup to make | 150     // Pretty much the same deal as the calibration: do some warmup to make | 
| 143     // sure we're timing steady-state pipelined frames. | 151     // sure we're timing steady-state pipelined frames. | 
| 144     for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 152     for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 
| 145         time(loops, bench, canvas, gl); | 153         time(loops, bench, canvas, gl); | 
| 146     } | 154     } | 
| 147 | 155 | 
| 148     // Now, actually do the timing! | 156     // Now, actually do the timing! | 
| 149     for (int i = 0; i < FLAGS_samples; i++) { | 157     for (int i = 0; i < FLAGS_samples; i++) { | 
| 150         samples[i] = time(loops, bench, canvas, gl) / loops; | 158         samples[i] = time(loops, bench, canvas, gl) / loops; | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 245     log->option("build", "RELEASE"); | 253     log->option("build", "RELEASE"); | 
| 246 #endif | 254 #endif | 
| 247 } | 255 } | 
| 248 | 256 | 
| 249 int tool_main(int argc, char** argv); | 257 int tool_main(int argc, char** argv); | 
| 250 int tool_main(int argc, char** argv) { | 258 int tool_main(int argc, char** argv) { | 
| 251     SetupCrashHandler(); | 259     SetupCrashHandler(); | 
| 252     SkAutoGraphics ag; | 260     SkAutoGraphics ag; | 
| 253     SkCommandLineFlags::Parse(argc, argv); | 261     SkCommandLineFlags::Parse(argc, argv); | 
| 254 | 262 | 
|  | 263     if (FLAGS_runOnce) { | 
|  | 264         FLAGS_samples     = 1; | 
|  | 265         FLAGS_gpuFrameLag = 0; | 
|  | 266     } | 
|  | 267 | 
| 255     MultiResultsWriter log; | 268     MultiResultsWriter log; | 
| 256     SkAutoTDelete<JSONResultsWriter> json; | 269     SkAutoTDelete<JSONResultsWriter> json; | 
| 257     if (!FLAGS_outResultsFile.isEmpty()) { | 270     if (!FLAGS_outResultsFile.isEmpty()) { | 
| 258         json.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0]))); | 271         json.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0]))); | 
| 259         log.add(json.get()); | 272         log.add(json.get()); | 
| 260     } | 273     } | 
| 261     CallEnd<MultiResultsWriter> ender(log); | 274     CallEnd<MultiResultsWriter> ender(log); | 
| 262     fill_static_options(&log); | 275     fill_static_options(&log); | 
| 263 | 276 | 
| 264     const double overhead = estimate_timer_overhead(); | 277     const double overhead = estimate_timer_overhead(); | 
| 265     SkAutoTMalloc<double> samples(FLAGS_samples); | 278     SkAutoTMalloc<double> samples(FLAGS_samples); | 
| 266 | 279 | 
| 267     if (FLAGS_verbose) { | 280     if (FLAGS_runOnce) { | 
|  | 281         SkDebugf("--runOnce is true; times would only be misleading so we won't 
     print them.\n"); | 
|  | 282     } else if (FLAGS_verbose) { | 
| 268         // No header. | 283         // No header. | 
| 269     } else if (FLAGS_quiet) { | 284     } else if (FLAGS_quiet) { | 
| 270         SkDebugf("median\tbench\tconfig\n"); | 285         SkDebugf("median\tbench\tconfig\n"); | 
| 271     } else { | 286     } else { | 
| 272         SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\
     n"); | 287         SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\
     n"); | 
| 273     } | 288     } | 
| 274 | 289 | 
| 275     for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next(
     )) { | 290     for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next(
     )) { | 
| 276         SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); | 291         SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); | 
| 277         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 292         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 298 | 313 | 
| 299             const char* config = targets[j]->config; | 314             const char* config = targets[j]->config; | 
| 300 | 315 | 
| 301             log.config(config); | 316             log.config(config); | 
| 302             log.timer("min_ms",    stats.min); | 317             log.timer("min_ms",    stats.min); | 
| 303             log.timer("median_ms", stats.median); | 318             log.timer("median_ms", stats.median); | 
| 304             log.timer("mean_ms",   stats.mean); | 319             log.timer("mean_ms",   stats.mean); | 
| 305             log.timer("max_ms",    stats.max); | 320             log.timer("max_ms",    stats.max); | 
| 306             log.timer("stddev_ms", sqrt(stats.var)); | 321             log.timer("stddev_ms", sqrt(stats.var)); | 
| 307 | 322 | 
| 308             if (FLAGS_verbose) { | 323             if (FLAGS_runOnce) { | 
|  | 324                 if (targets.count() == 1) { | 
|  | 325                     config = ""; // Only print the config if we run the same ben
     ch on more than one. | 
|  | 326                 } | 
|  | 327                 SkDebugf("%s\t%s\n", bench->getName(), config); | 
|  | 328             } else if (FLAGS_verbose) { | 
| 309                 for (int i = 0; i < FLAGS_samples; i++) { | 329                 for (int i = 0; i < FLAGS_samples; i++) { | 
| 310                     SkDebugf("%s  ", humanize(samples[i]).c_str()); | 330                     SkDebugf("%s  ", humanize(samples[i]).c_str()); | 
| 311                 } | 331                 } | 
| 312                 SkDebugf("%s\n", bench->getName()); | 332                 SkDebugf("%s\n", bench->getName()); | 
| 313             } else if (FLAGS_quiet) { | 333             } else if (FLAGS_quiet) { | 
| 314                 if (targets.count() == 1) { | 334                 if (targets.count() == 1) { | 
| 315                     config = ""; // Only print the config if we run the same ben
     ch on more than one. | 335                     config = ""; // Only print the config if we run the same ben
     ch on more than one. | 
| 316                 } | 336                 } | 
| 317                 SkDebugf("%s\t%s\t%s\n", humanize(stats.median).c_str(), bench->
     getName(), config); | 337                 SkDebugf("%s\t%s\t%s\n", humanize(stats.median).c_str(), bench->
     getName(), config); | 
| 318             } else { | 338             } else { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 334     } | 354     } | 
| 335 | 355 | 
| 336     return 0; | 356     return 0; | 
| 337 } | 357 } | 
| 338 | 358 | 
| 339 #if !defined SK_BUILD_FOR_IOS | 359 #if !defined SK_BUILD_FOR_IOS | 
| 340 int main(int argc, char * const argv[]) { | 360 int main(int argc, char * const argv[]) { | 
| 341     return tool_main(argc, (char**) argv); | 361     return tool_main(argc, (char**) argv); | 
| 342 } | 362 } | 
| 343 #endif | 363 #endif | 
| OLD | NEW | 
|---|