Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: bench/benchmain.cpp

Issue 23536046: Try for better bench stability. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: tune default settings a bit more towards slower and more precise Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « bench/DeferredCanvasBench.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #if SK_SUPPORT_GPU 9 #if SK_SUPPORT_GPU
10 #include "GrContext.h" 10 #include "GrContext.h"
(...skipping 19 matching lines...) Expand all
30 #include "SkPicture.h" 30 #include "SkPicture.h"
31 #include "SkString.h" 31 #include "SkString.h"
32 32
33 enum BenchMode { 33 enum BenchMode {
34 kNormal_BenchMode, 34 kNormal_BenchMode,
35 kDeferred_BenchMode, 35 kDeferred_BenchMode,
36 kDeferredSilent_BenchMode, 36 kDeferredSilent_BenchMode,
37 kRecord_BenchMode, 37 kRecord_BenchMode,
38 kPictureRecord_BenchMode 38 kPictureRecord_BenchMode
39 }; 39 };
40 const char* BenchMode_Name[] = { "normal", "deferred", "deferredSilent", "record ", "picturerecord" }; 40 const char* BenchMode_Name[] = {
41 "normal", "deferred", "deferredSilent", "record", "picturerecord"
42 };
41 43
42 /////////////////////////////////////////////////////////////////////////////// 44 ///////////////////////////////////////////////////////////////////////////////
43 45
44 static void erase(SkBitmap& bm) { 46 static void erase(SkBitmap& bm) {
45 if (bm.config() == SkBitmap::kA8_Config) { 47 if (bm.config() == SkBitmap::kA8_Config) {
46 bm.eraseColor(SK_ColorTRANSPARENT); 48 bm.eraseColor(SK_ColorTRANSPARENT);
47 } else { 49 } else {
48 bm.eraseColor(SK_ColorWHITE); 50 bm.eraseColor(SK_ColorWHITE);
49 } 51 }
50 } 52 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 "If a test does not match any list entry,\n" 266 "If a test does not match any list entry,\n"
265 "it is skipped unless some list entry starts with ~\n" ); 267 "it is skipped unless some list entry starts with ~\n" );
266 DEFINE_string(mode, "normal", 268 DEFINE_string(mode, "normal",
267 "normal: draw to a normal canvas;\n" 269 "normal: draw to a normal canvas;\n"
268 "deferred: draw to a deferred canvas;\n" 270 "deferred: draw to a deferred canvas;\n"
269 "deferredSilent: deferred with silent playback;\n" 271 "deferredSilent: deferred with silent playback;\n"
270 "record: draw to an SkPicture;\n" 272 "record: draw to an SkPicture;\n"
271 "picturerecord: draw from an SkPicture to an SkPicture.\n"); 273 "picturerecord: draw from an SkPicture to an SkPicture.\n");
272 DEFINE_string(config, "", "Run configs given. If empty, runs the defaults set i n gConfigs."); 274 DEFINE_string(config, "", "Run configs given. If empty, runs the defaults set i n gConfigs.");
273 DEFINE_string(logFile, "", "Also write stdout here."); 275 DEFINE_string(logFile, "", "Also write stdout here.");
274 DEFINE_int32(benchMs, 20, "Target time in ms to run each benchmark config."); 276 DEFINE_int32(minMs, 20, "Shortest time we'll allow a benchmark to run.");
277 DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
278 DEFINE_double(error, 0.01,
279 "Ratio of subsequent bench measurements must drop within 1±error t o converge.");
275 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops."); 280 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
281 DEFINE_bool2(verbose, v, false, "Print more.");
282
283 // Has this bench converged? First arguments are milliseconds / loop iteration,
284 // last is overall runtime in milliseconds.
285 static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
286 if (currRaw < FLAGS_minMs) {
287 return false;
288 }
289 const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
290 const double ratio = currPerLoop / prevPerLoop;
291 return low < ratio && ratio < high;
292 }
276 293
277 int tool_main(int argc, char** argv); 294 int tool_main(int argc, char** argv);
278 int tool_main(int argc, char** argv) { 295 int tool_main(int argc, char** argv) {
279 #if SK_ENABLE_INST_COUNT 296 #if SK_ENABLE_INST_COUNT
280 gPrintInstCount = true; 297 gPrintInstCount = true;
281 #endif 298 #endif
282 SkAutoGraphics ag; 299 SkAutoGraphics ag;
283 SkCommandLineFlags::Parse(argc, argv); 300 SkCommandLineFlags::Parse(argc, argv);
284 301
285 // First, parse some flags. 302 // First, parse some flags.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 349 }
333 } 350 }
334 } 351 }
335 #if SK_SUPPORT_GPU 352 #if SK_SUPPORT_GPU
336 for (int i = 0; i < configs.count(); ++i) { 353 for (int i = 0; i < configs.count(); ++i) {
337 const Config& config = gConfigs[configs[i]]; 354 const Config& config = gConfigs[configs[i]];
338 355
339 if (kGPU_Backend == config.backend) { 356 if (kGPU_Backend == config.backend) {
340 GrContext* context = gContextFactory.get(config.contextType); 357 GrContext* context = gContextFactory.get(config.contextType);
341 if (NULL == context) { 358 if (NULL == context) {
342 SkString error; 359 logger.logError(SkStringPrintf(
343 error.printf("Error creating GrContext for config %s. Config wil l be skipped.\n", 360 "Error creating GrContext for config %s. Config will be skip ped.\n",
344 config.name); 361 config.name));
345 logger.logError(error);
346 configs.remove(i); 362 configs.remove(i);
347 --i; 363 --i;
348 continue; 364 continue;
349 } 365 }
350 if (config.sampleCount > context->getMaxSampleCount()){ 366 if (config.sampleCount > context->getMaxSampleCount()){
351 SkString error; 367 logger.logError(SkStringPrintf(
352 error.printf("Sample count (%d) for config %s is unsupported. " 368 "Sample count (%d) for config %s is unsupported. Config will be skipped.\n",
353 "Config will be skipped.\n", 369 config.sampleCount, config.name));
354 config.sampleCount, config.name);
355 logger.logError(error);
356 configs.remove(i); 370 configs.remove(i);
357 --i; 371 --i;
358 continue; 372 continue;
359 } 373 }
360 } 374 }
361 } 375 }
362 #endif 376 #endif
363 377
364 // All flags should be parsed now. Report our settings. 378 // All flags should be parsed now. Report our settings.
365 if (kIsDebug) { 379 if (kIsDebug) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 const SkPicture::RecordingFlags kRecordFlags = 491 const SkPicture::RecordingFlags kRecordFlags =
478 SkPicture::kUsePathBoundsForClip_RecordingFlag; 492 SkPicture::kUsePathBoundsForClip_RecordingFlag;
479 493
480 if (kNonRendering_Backend != config.backend) { 494 if (kNonRendering_Backend != config.backend) {
481 device.reset(make_device(config.config, 495 device.reset(make_device(config.config,
482 dim, 496 dim,
483 config.backend, 497 config.backend,
484 config.sampleCount, 498 config.sampleCount,
485 context)); 499 context));
486 if (!device.get()) { 500 if (!device.get()) {
487 SkString error; 501 logger.logError(SkStringPrintf(
488 error.printf("Device creation failure for config %s. Will sk ip.\n", config.name); 502 "Device creation failure for config %s. Will skip.\n", c onfig.name));
489 logger.logError(error);
490 continue; 503 continue;
491 } 504 }
492 505
493 switch(benchMode) { 506 switch(benchMode) {
494 case kDeferredSilent_BenchMode: 507 case kDeferredSilent_BenchMode:
495 case kDeferred_BenchMode: 508 case kDeferred_BenchMode:
496 canvas.reset(SkDeferredCanvas::Create(device.get())); 509 canvas.reset(SkDeferredCanvas::Create(device.get()));
497 break; 510 break;
498 case kRecord_BenchMode: 511 case kRecord_BenchMode:
499 canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.f Y, kRecordFlags))); 512 canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.f Y, kRecordFlags)));
(...skipping 28 matching lines...) Expand all
528 541
529 #if SK_SUPPORT_GPU 542 #if SK_SUPPORT_GPU
530 SkGLContextHelper* contextHelper = NULL; 543 SkGLContextHelper* contextHelper = NULL;
531 if (kGPU_Backend == config.backend) { 544 if (kGPU_Backend == config.backend) {
532 contextHelper = gContextFactory.getGLContext(config.contextType) ; 545 contextHelper = gContextFactory.getGLContext(config.contextType) ;
533 } 546 }
534 BenchTimer timer(contextHelper); 547 BenchTimer timer(contextHelper);
535 #else 548 #else
536 BenchTimer timer; 549 BenchTimer timer;
537 #endif 550 #endif
538 551
robertphillips 2013/09/13 20:00:59 You're sure about this?
mtklein 2013/09/13 20:07:46 Yep. Shortest way I know to write a double +inf.
552 double previous = 1.0/0.0;
553 bool converged = false;
539 bench->setLoops(0); 554 bench->setLoops(0);
robertphillips 2013/09/13 20:00:59 if () { }
mtklein 2013/09/13 20:07:46 Done.
555 if (FLAGS_verbose) SkDebugf("%s %s: ", bench->getName(), config.name );
540 do { 556 do {
541 // Ramp up 1 -> 4 -> 16 -> ... -> ~1 billion. 557 // Ramp up 1 -> 4 -> 16 -> ... -> ~1 billion.
542 const int loops = bench->getLoops(); 558 const int loops = bench->getLoops();
543 if (loops >= (1<<30)) { 559 if (loops >= (1<<30) || timer.fWall > FLAGS_maxMs) {
544 // If you find it takes more than a billion loops to get up to 20ms of runtime, 560 // If you find it takes more than a billion loops to get up to 20ms of runtime,
545 // you've got a computer clocked at several THz or have a br oken benchmark. ;) 561 // you've got a computer clocked at several THz or have a br oken benchmark. ;)
546 // "1B ought to be enough for anybody." 562 // "1B ought to be enough for anybody."
547 SkString str; 563 logger.logError(SkStringPrintf(
548 str.printf("Can't ramp %s to %dms.\n", bench->getName(), FLA GS_benchMs); 564 "Can't get %s %s to converge in %dms.\n",
549 logger.logError(str); 565 bench->getName(), config.name, FLAGS_maxMs));
550 break; 566 break;
551 } 567 }
552 bench->setLoops(loops == 0 ? 1 : loops * 4); 568 bench->setLoops(loops == 0 ? 1 : loops * 2);
553 569
554 if ((benchMode == kRecord_BenchMode || benchMode == kPictureReco rd_BenchMode)) { 570 if ((benchMode == kRecord_BenchMode || benchMode == kPictureReco rd_BenchMode)) {
555 // Clear the recorded commands so that they do not accumulat e. 571 // Clear the recorded commands so that they do not accumulat e.
556 canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecord Flags)); 572 canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecord Flags));
557 } 573 }
558 574
559 timer.start(); 575 timer.start();
560 if (NULL != canvas) { 576 if (NULL != canvas) {
561 canvas->save(); 577 canvas->save();
562 } 578 }
(...skipping 16 matching lines...) Expand all
579 595
580 // Stop truncated timers before GL calls complete, and stop the full timers after. 596 // Stop truncated timers before GL calls complete, and stop the full timers after.
581 timer.truncatedEnd(); 597 timer.truncatedEnd();
582 #if SK_SUPPORT_GPU 598 #if SK_SUPPORT_GPU
583 if (NULL != glContext) { 599 if (NULL != glContext) {
584 context->flush(); 600 context->flush();
585 SK_GL(*glContext, Finish()); 601 SK_GL(*glContext, Finish());
586 } 602 }
587 #endif 603 #endif
588 timer.end(); 604 timer.end();
589 } while (!kIsDebug && timer.fWall < FLAGS_benchMs); // One loop onl y in debug mode. 605 const double current = timer.fWall / bench->getLoops();
robertphillips 2013/09/13 20:00:59 if () { }
mtklein 2013/09/13 20:07:46 Done.
606 if (FLAGS_verbose && current > previous) SkDebugf("↑");
robertphillips 2013/09/13 20:00:59 same here
mtklein 2013/09/13 20:07:46 Done.
607 if (FLAGS_verbose) SkDebugf("%.3g ", current);
608 converged = HasConverged(previous, current, timer.fWall);
609 previous = current;
610 } while (!kIsDebug && !converged);
robertphillips 2013/09/13 20:00:59 and here
mtklein 2013/09/13 20:07:46 Done.
611 if (FLAGS_verbose) SkDebugf("\n");
590 612
591 if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) { 613 if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) {
592 saveFile(bench->getName(), 614 saveFile(bench->getName(),
593 config.name, 615 config.name,
594 FLAGS_outDir[0], 616 FLAGS_outDir[0],
595 device->accessBitmap(false)); 617 device->accessBitmap(false));
596 } 618 }
597 619
598 if (kIsDebug) { 620 if (kIsDebug) {
599 // Let's not mislead ourselves by looking at Debug build bench t imes! 621 // Let's not mislead ourselves by looking at Debug build bench t imes!
(...skipping 28 matching lines...) Expand all
628 gContextFactory.destroyContexts(); 650 gContextFactory.destroyContexts();
629 #endif 651 #endif
630 return 0; 652 return 0;
631 } 653 }
632 654
633 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 655 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
634 int main(int argc, char * const argv[]) { 656 int main(int argc, char * const argv[]) {
635 return tool_main(argc, (char**) argv); 657 return tool_main(argc, (char**) argv);
636 } 658 }
637 #endif 659 #endif
OLDNEW
« no previous file with comments | « bench/DeferredCanvasBench.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698