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

Side by Side Diff: bench/benchmain.cpp

Issue 83863002: Add JSON output option to bench. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Added some more comments. Created 7 years 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/ResultsWriter.h ('k') | gm/gm_expectations.h » ('j') | 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 * Copyright 2011 Google Inc. 2 * Copyright 2011 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 "BenchTimer.h" 8 #include "BenchTimer.h"
9 #include "ResultsWriter.h"
9 #include "SkBenchLogger.h" 10 #include "SkBenchLogger.h"
10 #include "SkBenchmark.h" 11 #include "SkBenchmark.h"
11 #include "SkBitmapDevice.h" 12 #include "SkBitmapDevice.h"
12 #include "SkCanvas.h" 13 #include "SkCanvas.h"
13 #include "SkColorPriv.h" 14 #include "SkColorPriv.h"
14 #include "SkCommandLineFlags.h" 15 #include "SkCommandLineFlags.h"
15 #include "SkDeferredCanvas.h" 16 #include "SkDeferredCanvas.h"
16 #include "SkGraphics.h" 17 #include "SkGraphics.h"
17 #include "SkImageEncoder.h" 18 #include "SkImageEncoder.h"
18 #include "SkOSFile.h" 19 #include "SkOSFile.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 DEFINE_string(config, kDefaultsConfigStr, 269 DEFINE_string(config, kDefaultsConfigStr,
269 "Run configs given. By default, runs the configs marked \"runByDe fault\" in gConfigs."); 270 "Run configs given. By default, runs the configs marked \"runByDe fault\" in gConfigs.");
270 DEFINE_string(logFile, "", "Also write stdout here."); 271 DEFINE_string(logFile, "", "Also write stdout here.");
271 DEFINE_int32(minMs, 20, "Shortest time we'll allow a benchmark to run."); 272 DEFINE_int32(minMs, 20, "Shortest time we'll allow a benchmark to run.");
272 DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run."); 273 DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
273 DEFINE_double(error, 0.01, 274 DEFINE_double(error, 0.01,
274 "Ratio of subsequent bench measurements must drop within 1±error t o converge."); 275 "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."); 276 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
276 DEFINE_bool2(verbose, v, false, "Print more."); 277 DEFINE_bool2(verbose, v, false, "Print more.");
277 DEFINE_string2(resourcePath, i, NULL, "directory for test resources."); 278 DEFINE_string2(resourcePath, i, NULL, "directory for test resources.");
279 DEFINE_string(outResultsFile, "", "If given, the results will be written to the file in JSON format.");
278 280
279 // Has this bench converged? First arguments are milliseconds / loop iteration, 281 // Has this bench converged? First arguments are milliseconds / loop iteration,
280 // last is overall runtime in milliseconds. 282 // last is overall runtime in milliseconds.
281 static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) { 283 static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
282 if (currRaw < FLAGS_minMs) { 284 if (currRaw < FLAGS_minMs) {
283 return false; 285 return false;
284 } 286 }
285 const double low = 1 - FLAGS_error, high = 1 + FLAGS_error; 287 const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
286 const double ratio = currPerLoop / prevPerLoop; 288 const double ratio = currPerLoop / prevPerLoop;
287 return low < ratio && ratio < high; 289 return low < ratio && ratio < high;
288 } 290 }
289 291
290 int tool_main(int argc, char** argv); 292 int tool_main(int argc, char** argv);
291 int tool_main(int argc, char** argv) { 293 int tool_main(int argc, char** argv) {
292 #if SK_ENABLE_INST_COUNT 294 #if SK_ENABLE_INST_COUNT
293 gPrintInstCount = true; 295 gPrintInstCount = true;
294 #endif 296 #endif
295 SkAutoGraphics ag; 297 SkAutoGraphics ag;
296 SkCommandLineFlags::Parse(argc, argv); 298 SkCommandLineFlags::Parse(argc, argv);
297 299
298 // First, parse some flags. 300 // First, parse some flags.
299
300 SkBenchLogger logger; 301 SkBenchLogger logger;
301 if (FLAGS_logFile.count()) { 302 if (FLAGS_logFile.count()) {
302 logger.SetLogFile(FLAGS_logFile[0]); 303 logger.SetLogFile(FLAGS_logFile[0]);
303 } 304 }
304 305
306 LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]);
307 MultiResultsWriter writer;
308 writer.add(&logWriter);
309 JSONResultsWriter* jsonWriter = NULL;
djsollen 2013/11/25 18:09:59 use the SkAutoTDelete template and you won't need
jcgregorio 2013/11/25 19:03:58 Done.
310 if (FLAGS_outResultsFile.count()) {
311 jsonWriter = SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0]));
312 writer.add(jsonWriter);
313 }
314
305 const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF; 315 const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
306 SkTriState::State dither = SkTriState::kDefault; 316 SkTriState::State dither = SkTriState::kDefault;
307 for (size_t i = 0; i < 3; i++) { 317 for (size_t i = 0; i < 3; i++) {
308 if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) { 318 if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
309 dither = static_cast<SkTriState::State>(i); 319 dither = static_cast<SkTriState::State>(i);
310 } 320 }
311 } 321 }
312 322
313 BenchMode benchMode = kNormal_BenchMode; 323 BenchMode benchMode = kNormal_BenchMode;
314 for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) { 324 for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 387 }
378 } 388 }
379 } 389 }
380 #endif 390 #endif
381 391
382 // All flags should be parsed now. Report our settings. 392 // All flags should be parsed now. Report our settings.
383 if (kIsDebug) { 393 if (kIsDebug) {
384 logger.logError("bench was built in Debug mode, so we're going to hide t he times." 394 logger.logError("bench was built in Debug mode, so we're going to hide t he times."
385 " It's for your own good!\n"); 395 " It's for your own good!\n");
386 } 396 }
387 SkString str("skia bench:"); 397 writer.option("mode", FLAGS_mode[0]);
388 str.appendf(" mode=%s", FLAGS_mode[0]); 398 writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str());
389 str.appendf(" alpha=0x%02X antialias=%d filter=%d dither=%s", 399 writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str());
390 alpha, FLAGS_forceAA, FLAGS_forceFilter, SkTriState::Name[dither ]); 400 writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str());
391 str.appendf(" rotate=%d scale=%d clip=%d", FLAGS_rotate, FLAGS_scale, FLAGS_ clip); 401 writer.option("dither", SkTriState::Name[dither]);
402
403 writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str());
404 writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str());
405 writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str());
392 406
393 #if defined(SK_SCALAR_IS_FIXED) 407 #if defined(SK_SCALAR_IS_FIXED)
394 str.append(" scalar=fixed"); 408 writer.option("scalar", "fixed");
395 #else 409 #else
396 str.append(" scalar=float"); 410 writer.option("scalar", "float");
397 #endif 411 #endif
398 412
399 #if defined(SK_BUILD_FOR_WIN32) 413 #if defined(SK_BUILD_FOR_WIN32)
400 str.append(" system=WIN32"); 414 writer.option("system", "WIN32");
401 #elif defined(SK_BUILD_FOR_MAC) 415 #elif defined(SK_BUILD_FOR_MAC)
402 str.append(" system=MAC"); 416 writer.option("system", "MAC");
403 #elif defined(SK_BUILD_FOR_ANDROID) 417 #elif defined(SK_BUILD_FOR_ANDROID)
404 str.append(" system=ANDROID"); 418 writer.option("system", "ANDROID");
405 #elif defined(SK_BUILD_FOR_UNIX) 419 #elif defined(SK_BUILD_FOR_UNIX)
406 str.append(" system=UNIX"); 420 writer.option("system", "UNIX");
407 #else 421 #else
408 str.append(" system=other"); 422 writer.option("system", "other");
409 #endif 423 #endif
410 424
411 #if defined(SK_DEBUG) 425 #if defined(SK_DEBUG)
412 str.append(" DEBUG"); 426 writer.option("build", "DEBUG");
427 #else
428 writer.option("build", "RELEASE");
413 #endif 429 #endif
414 str.append("\n");
415 logger.logProgress(str);
416
417 430
418 // Set texture cache limits if non-default. 431 // Set texture cache limits if non-default.
419 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { 432 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
420 #if SK_SUPPORT_GPU 433 #if SK_SUPPORT_GPU
421 const Config& config = gConfigs[i]; 434 const Config& config = gConfigs[i];
422 if (SkBenchmark::kGPU_Backend != config.backend) { 435 if (SkBenchmark::kGPU_Backend != config.backend) {
423 continue; 436 continue;
424 } 437 }
425 GrContext* context = gContextFactory.get(config.contextType); 438 GrContext* context = gContextFactory.get(config.contextType);
426 if (NULL == context) { 439 if (NULL == context) {
427 continue; 440 continue;
428 } 441 }
429 442
430 size_t bytes; 443 size_t bytes;
431 int count; 444 int count;
432 context->getTextureCacheLimits(&count, &bytes); 445 context->getTextureCacheLimits(&count, &bytes);
433 if (-1 != FLAGS_gpuCacheBytes) { 446 if (-1 != FLAGS_gpuCacheBytes) {
434 bytes = static_cast<size_t>(FLAGS_gpuCacheBytes); 447 bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
435 } 448 }
436 if (-1 != FLAGS_gpuCacheCount) { 449 if (-1 != FLAGS_gpuCacheCount) {
437 count = FLAGS_gpuCacheCount; 450 count = FLAGS_gpuCacheCount;
438 } 451 }
439 context->setTextureCacheLimits(count, bytes); 452 context->setTextureCacheLimits(count, bytes);
440 #endif 453 #endif
441 } 454 }
442 455
443 // Find the longest name of the benches we're going to run to make the outpu t pretty.
444 Iter names;
445 SkBenchmark* bench;
446 size_t longestName = 0;
447 while ((bench = names.next()) != NULL) {
448 SkAutoTUnref<SkBenchmark> benchUnref(bench);
449 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
450 continue;
451 }
452 const size_t length = strlen(bench->getName());
453 longestName = length > longestName ? length : longestName;
454 }
455
456 // Run each bench in each configuration it supports and we asked for. 456 // Run each bench in each configuration it supports and we asked for.
457 Iter iter; 457 Iter iter;
458 SkBenchmark* bench;
458 while ((bench = iter.next()) != NULL) { 459 while ((bench = iter.next()) != NULL) {
459 SkAutoTUnref<SkBenchmark> benchUnref(bench); 460 SkAutoTUnref<SkBenchmark> benchUnref(bench);
460 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { 461 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
461 continue; 462 continue;
462 } 463 }
463 464
464 bench->setForceAlpha(alpha); 465 bench->setForceAlpha(alpha);
465 bench->setForceAA(FLAGS_forceAA); 466 bench->setForceAA(FLAGS_forceAA);
466 bench->setForceFilter(FLAGS_forceFilter); 467 bench->setForceFilter(FLAGS_forceFilter);
467 bench->setDither(dither); 468 bench->setDither(dither);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 531
531 if (NULL != canvas) { 532 if (NULL != canvas) {
532 canvas->clear(SK_ColorWHITE); 533 canvas->clear(SK_ColorWHITE);
533 if (FLAGS_clip) { performClip(canvas, dim.fX, dim.fY); } 534 if (FLAGS_clip) { performClip(canvas, dim.fX, dim.fY); }
534 if (FLAGS_scale) { performScale(canvas, dim.fX, dim.fY); } 535 if (FLAGS_scale) { performScale(canvas, dim.fX, dim.fY); }
535 if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); } 536 if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); }
536 } 537 }
537 538
538 if (!loggedBenchName) { 539 if (!loggedBenchName) {
539 loggedBenchName = true; 540 loggedBenchName = true;
540 SkString str; 541 writer.bench(bench->getName(), dim.fX, dim.fY);
541 str.printf("running bench [%3d %3d] %*s ",
542 dim.fX, dim.fY, (int)longestName, bench->getName());
543 logger.logProgress(str);
544 } 542 }
545 543
546 #if SK_SUPPORT_GPU 544 #if SK_SUPPORT_GPU
547 SkGLContextHelper* contextHelper = NULL; 545 SkGLContextHelper* contextHelper = NULL;
548 if (SkBenchmark::kGPU_Backend == config.backend) { 546 if (SkBenchmark::kGPU_Backend == config.backend) {
549 contextHelper = gContextFactory.getGLContext(config.contextType) ; 547 contextHelper = gContextFactory.getGLContext(config.contextType) ;
550 } 548 }
551 BenchTimer timer(contextHelper); 549 BenchTimer timer(contextHelper);
552 #else 550 #else
553 BenchTimer timer; 551 BenchTimer timer;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 // Normalize to ms per 1000 iterations. 670 // Normalize to ms per 1000 iterations.
673 const double normalize = 1000.0 / loopsPerIter; 671 const double normalize = 1000.0 / loopsPerIter;
674 const struct { char shortName; const char* longName; double ms; } ti mes[] = { 672 const struct { char shortName; const char* longName; double ms; } ti mes[] = {
675 {'w', "msecs", normalize * timer.fWall}, 673 {'w', "msecs", normalize * timer.fWall},
676 {'W', "Wmsecs", normalize * timer.fTruncatedWall}, 674 {'W', "Wmsecs", normalize * timer.fTruncatedWall},
677 {'c', "cmsecs", normalize * timer.fCpu}, 675 {'c', "cmsecs", normalize * timer.fCpu},
678 {'C', "Cmsecs", normalize * timer.fTruncatedCpu}, 676 {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
679 {'g', "gmsecs", normalize * timer.fGpu}, 677 {'g', "gmsecs", normalize * timer.fGpu},
680 }; 678 };
681 679
682 SkString result; 680 writer.config(config.name);
683 result.appendf(" %s:", config.name);
684 for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) { 681 for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
685 if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) { 682 if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
686 result.appendf(" %s = ", times[i].longName); 683 writer.timer(times[i].longName, times[i].ms);
687 result.appendf(FLAGS_timeFormat[0], times[i].ms);
688 } 684 }
689 } 685 }
690 logger.logProgress(result);
691 }
692 if (loggedBenchName) {
693 logger.logProgress("\n");
694 } 686 }
695 } 687 }
688 writer.end();
djsollen 2013/11/25 18:09:59 could you have some sort of stack wrapper that wou
jcgregorio 2013/11/25 19:03:58 Done. See CallEnd<> above.
689 SkDELETE(jsonWriter);
696 #if SK_SUPPORT_GPU 690 #if SK_SUPPORT_GPU
697 gContextFactory.destroyContexts(); 691 gContextFactory.destroyContexts();
698 #endif 692 #endif
699 return 0; 693 return 0;
700 } 694 }
701 695
702 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 696 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
703 int main(int argc, char * const argv[]) { 697 int main(int argc, char * const argv[]) {
704 return tool_main(argc, (char**) argv); 698 return tool_main(argc, (char**) argv);
705 } 699 }
706 #endif 700 #endif
OLDNEW
« no previous file with comments | « bench/ResultsWriter.h ('k') | gm/gm_expectations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698