| 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" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 156 |
| 157 static int kFailedLoops = -2; | 157 static int kFailedLoops = -2; |
| 158 static int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas,
double* samples) { | 158 static int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas,
double* samples) { |
| 159 // First figure out approximately how many loops of bench it takes to make o
verhead negligible. | 159 // First figure out approximately how many loops of bench it takes to make o
verhead negligible. |
| 160 double bench_plus_overhead = 0.0; | 160 double bench_plus_overhead = 0.0; |
| 161 int round = 0; | 161 int round = 0; |
| 162 if (kAutoTuneLoops == FLAGS_loops) { | 162 if (kAutoTuneLoops == FLAGS_loops) { |
| 163 while (bench_plus_overhead < overhead) { | 163 while (bench_plus_overhead < overhead) { |
| 164 if (round++ == FLAGS_maxCalibrationAttempts) { | 164 if (round++ == FLAGS_maxCalibrationAttempts) { |
| 165 SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skip
ping.\n", | 165 SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skip
ping.\n", |
| 166 bench->getName(), HUMANIZE(bench_plus_overhead), HUMANI
ZE(overhead)); | 166 bench->getUniqueName(), HUMANIZE(bench_plus_overhead),
HUMANIZE(overhead)); |
| 167 return kFailedLoops; | 167 return kFailedLoops; |
| 168 } | 168 } |
| 169 bench_plus_overhead = time(1, bench, canvas, NULL); | 169 bench_plus_overhead = time(1, bench, canvas, NULL); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 // Later we'll just start and stop the timer once but loop N times. | 173 // Later we'll just start and stop the timer once but loop N times. |
| 174 // We'll pick N to make timer overhead negligible: | 174 // We'll pick N to make timer overhead negligible: |
| 175 // | 175 // |
| 176 // overhead | 176 // overhead |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 SkDebugf("maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tb
ench\n", | 585 SkDebugf("maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tb
ench\n", |
| 586 FLAGS_samples, "samples"); | 586 FLAGS_samples, "samples"); |
| 587 } | 587 } |
| 588 | 588 |
| 589 SkTDArray<Config> configs; | 589 SkTDArray<Config> configs; |
| 590 create_configs(&configs); | 590 create_configs(&configs); |
| 591 | 591 |
| 592 BenchmarkStream benchStream; | 592 BenchmarkStream benchStream; |
| 593 while (Benchmark* b = benchStream.next()) { | 593 while (Benchmark* b = benchStream.next()) { |
| 594 SkAutoTDelete<Benchmark> bench(b); | 594 SkAutoTDelete<Benchmark> bench(b); |
| 595 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 595 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()))
{ |
| 596 continue; | 596 continue; |
| 597 } | 597 } |
| 598 | 598 |
| 599 SkTDArray<Target*> targets; | 599 SkTDArray<Target*> targets; |
| 600 create_targets(&targets, bench.get(), configs); | 600 create_targets(&targets, bench.get(), configs); |
| 601 | 601 |
| 602 if (!targets.isEmpty()) { | 602 if (!targets.isEmpty()) { |
| 603 log->bench(bench->getName(), bench->getSize().fX, bench->getSize().f
Y); | 603 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); |
| 604 bench->preDraw(); | 604 bench->preDraw(); |
| 605 } | 605 } |
| 606 for (int j = 0; j < targets.count(); j++) { | 606 for (int j = 0; j < targets.count(); j++) { |
| 607 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
getCanvas() : NULL; | 607 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
getCanvas() : NULL; |
| 608 const char* config = targets[j]->config.name; | 608 const char* config = targets[j]->config.name; |
| 609 | 609 |
| 610 const int loops = | 610 const int loops = |
| 611 #if SK_SUPPORT_GPU | 611 #if SK_SUPPORT_GPU |
| 612 Benchmark::kGPU_Backend == targets[j]->config.backend | 612 Benchmark::kGPU_Backend == targets[j]->config.backend |
| 613 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) | 613 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) |
| 614 : | 614 : |
| 615 #endif | 615 #endif |
| 616 cpu_bench( overhead, bench.get(), canvas, samples.get()); | 616 cpu_bench( overhead, bench.get(), canvas, samples.get()); |
| 617 | 617 |
| 618 if (canvas && !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { | 618 if (canvas && !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { |
| 619 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); | 619 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); |
| 620 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getName
()); | 620 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); |
| 621 pngFilename.append(".png"); | 621 pngFilename.append(".png"); |
| 622 write_canvas_png(canvas, pngFilename); | 622 write_canvas_png(canvas, pngFilename); |
| 623 } | 623 } |
| 624 | 624 |
| 625 if (kFailedLoops == loops) { | 625 if (kFailedLoops == loops) { |
| 626 // Can't be timed. A warning note has already been printed. | 626 // Can't be timed. A warning note has already been printed. |
| 627 continue; | 627 continue; |
| 628 } | 628 } |
| 629 | 629 |
| 630 Stats stats(samples.get(), FLAGS_samples); | 630 Stats stats(samples.get(), FLAGS_samples); |
| 631 log->config(config); | 631 log->config(config); |
| 632 log->configOption("name", bench->getName()); |
| 632 benchStream.fillCurrentOptions(log.get()); | 633 benchStream.fillCurrentOptions(log.get()); |
| 633 #if SK_SUPPORT_GPU | 634 #if SK_SUPPORT_GPU |
| 634 if (Benchmark::kGPU_Backend == targets[j]->config.backend) { | 635 if (Benchmark::kGPU_Backend == targets[j]->config.backend) { |
| 635 fill_gpu_options(log.get(), targets[j]->gl); | 636 fill_gpu_options(log.get(), targets[j]->gl); |
| 636 } | 637 } |
| 637 #endif | 638 #endif |
| 638 log->timer("min_ms", stats.min); | 639 log->timer("min_ms", stats.min); |
| 639 log->timer("median_ms", stats.median); | 640 log->timer("median_ms", stats.median); |
| 640 log->timer("mean_ms", stats.mean); | 641 log->timer("mean_ms", stats.mean); |
| 641 log->timer("max_ms", stats.max); | 642 log->timer("max_ms", stats.max); |
| 642 log->timer("stddev_ms", sqrt(stats.var)); | 643 log->timer("stddev_ms", sqrt(stats.var)); |
| 643 | 644 |
| 644 if (kAutoTuneLoops != FLAGS_loops) { | 645 if (kAutoTuneLoops != FLAGS_loops) { |
| 645 if (targets.count() == 1) { | 646 if (targets.count() == 1) { |
| 646 config = ""; // Only print the config if we run the same ben
ch on more than one. | 647 config = ""; // Only print the config if we run the same ben
ch on more than one. |
| 647 } | 648 } |
| 648 SkDebugf("%s\t%s\n", bench->getName(), config); | 649 SkDebugf("%s\t%s\n", bench->getUniqueName(), config); |
| 649 } else if (FLAGS_verbose) { | 650 } else if (FLAGS_verbose) { |
| 650 for (int i = 0; i < FLAGS_samples; i++) { | 651 for (int i = 0; i < FLAGS_samples; i++) { |
| 651 SkDebugf("%s ", HUMANIZE(samples[i])); | 652 SkDebugf("%s ", HUMANIZE(samples[i])); |
| 652 } | 653 } |
| 653 SkDebugf("%s\n", bench->getName()); | 654 SkDebugf("%s\n", bench->getUniqueName()); |
| 654 } else if (FLAGS_quiet) { | 655 } else if (FLAGS_quiet) { |
| 655 if (targets.count() == 1) { | 656 if (targets.count() == 1) { |
| 656 config = ""; // Only print the config if we run the same ben
ch on more than one. | 657 config = ""; // Only print the config if we run the same ben
ch on more than one. |
| 657 } | 658 } |
| 658 SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getName(
), config); | 659 SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqu
eName(), config); |
| 659 } else { | 660 } else { |
| 660 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; | 661 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; |
| 661 SkDebugf("%4dM\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" | 662 SkDebugf("%4dM\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" |
| 662 , sk_tools::getMaxResidentSetSizeMB() | 663 , sk_tools::getMaxResidentSetSizeMB() |
| 663 , loops | 664 , loops |
| 664 , HUMANIZE(stats.min) | 665 , HUMANIZE(stats.min) |
| 665 , HUMANIZE(stats.median) | 666 , HUMANIZE(stats.median) |
| 666 , HUMANIZE(stats.mean) | 667 , HUMANIZE(stats.mean) |
| 667 , HUMANIZE(stats.max) | 668 , HUMANIZE(stats.max) |
| 668 , stddev_percent | 669 , stddev_percent |
| 669 , stats.plot.c_str() | 670 , stats.plot.c_str() |
| 670 , config | 671 , config |
| 671 , bench->getName() | 672 , bench->getUniqueName() |
| 672 ); | 673 ); |
| 673 } | 674 } |
| 674 } | 675 } |
| 675 targets.deleteAll(); | 676 targets.deleteAll(); |
| 676 | 677 |
| 677 #if SK_SUPPORT_GPU | 678 #if SK_SUPPORT_GPU |
| 678 if (FLAGS_abandonGpuContext) { | 679 if (FLAGS_abandonGpuContext) { |
| 679 gGrFactory->abandonContexts(); | 680 gGrFactory->abandonContexts(); |
| 680 } | 681 } |
| 681 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { | 682 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { |
| 682 gGrFactory->destroyContexts(); | 683 gGrFactory->destroyContexts(); |
| 683 } | 684 } |
| 684 #endif | 685 #endif |
| 685 } | 686 } |
| 686 | 687 |
| 687 return 0; | 688 return 0; |
| 688 } | 689 } |
| 689 | 690 |
| 690 #if !defined SK_BUILD_FOR_IOS | 691 #if !defined SK_BUILD_FOR_IOS |
| 691 int main(int argc, char** argv) { | 692 int main(int argc, char** argv) { |
| 692 SkCommandLineFlags::Parse(argc, argv); | 693 SkCommandLineFlags::Parse(argc, argv); |
| 693 return nanobench_main(); | 694 return nanobench_main(); |
| 694 } | 695 } |
| 695 #endif | 696 #endif |
| OLD | NEW |