| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // | 4 // |
| 5 // NOTE: See also wrapper script sdk/runtime/tools/bmu_benchmark_gallery.sh | 5 // NOTE: See also wrapper script sdk/runtime/tools/bmu_benchmark_gallery.sh |
| 6 // | 6 // |
| 7 // Tool to compute bounded mutator utilization (BMU) from a --verbose_gc log. | 7 // Tool to compute bounded mutator utilization (BMU) from a --verbose_gc log. |
| 8 // Outputs CSV suitable for, e.g., gnuplot: | 8 // Outputs CSV suitable for, e.g., gnuplot: |
| 9 // | 9 // |
| 10 // dart --verbose_gc foo.dart 2> foo.gclog | 10 // dart --verbose_gc foo.dart 2> foo.gclog |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 interesting.add(p.begin); | 49 interesting.add(p.begin); |
| 50 interesting.add(p.end); | 50 interesting.add(p.end); |
| 51 } | 51 } |
| 52 double result = 1.0; | 52 double result = 1.0; |
| 53 for (int i in interesting) { | 53 for (int i in interesting) { |
| 54 result = min(result, _utilization(new Interval(i, i + windowSize))); | 54 result = min(result, _utilization(new Interval(i, i + windowSize))); |
| 55 result = min(result, _utilization(new Interval(i - windowSize, i))); | 55 result = min(result, _utilization(new Interval(i - windowSize, i))); |
| 56 } | 56 } |
| 57 return result; | 57 return result; |
| 58 } | 58 } |
| 59 | 59 |
| 60 // Returns the fraction of non-pause time, or 1.0 for an invalid interval. | 60 // Returns the fraction of non-pause time, or 1.0 for an invalid interval. |
| 61 double _utilization(Interval<int> iv) { | 61 double _utilization(Interval<int> iv) { |
| 62 if (_run.begin > iv.begin || iv.end > _run.end || iv.length == 0) { | 62 if (_run.begin > iv.begin || iv.end > _run.end || iv.length == 0) { |
| 63 return 1.0; | 63 return 1.0; |
| 64 } | 64 } |
| 65 int paused = 0; | 65 int paused = 0; |
| 66 for (Interval<int> p in _pauses) { | 66 for (Interval<int> p in _pauses) { |
| 67 paused += p.overlap(iv).length; | 67 paused += p.overlap(iv).length; |
| 68 } | 68 } |
| 69 return 1.0 - (paused / iv.length); | 69 return 1.0 - (paused / iv.length); |
| 70 } | 70 } |
| 71 | 71 |
| 72 final Interval<int> _run = new Interval<int>(0, 0); | 72 final Interval<int> _run = new Interval<int>(0, 0); |
| 73 final List<Interval<int>> _pauses = []; | 73 final List<Interval<int>> _pauses = []; |
| 74 } | 74 } |
| 75 | 75 |
| 76 // Returns a GC pause as an interval in microseconds since program start, or | 76 // Returns a GC pause as an interval in microseconds since program start, or |
| 77 // the interval [0, 0) on parse error. | 77 // the interval [0, 0) on parse error. |
| 78 Interval<int> parseVerboseGCLine(String line) { | 78 Interval<int> parseVerboseGCLine(String line) { |
| 79 var fields = line.split(','); | 79 var fields = line.split(','); |
| 80 // Update this (and indices below, if needed) when logging format changes. | 80 // Update this (and indices below, if needed) when logging format changes. |
| 81 if (fields.length != 25) { | 81 if (fields.length != 25) { |
| 82 assert(line.startsWith('[ GC | space | count | start | gc time') || | 82 assert(line.startsWith('[ GC | space | count | start | gc time') || |
| 83 line.startsWith('[ (isolate)| (reason)| | (s) | (ms) ')); | 83 line.startsWith('[ (isolate)| (reason)| | (s) | (ms) ')); |
| 84 return new Interval<int>(0, 0); | 84 return new Interval<int>(0, 0); |
| 85 } | 85 } |
| 86 var begin = (1e6 * double.parse(fields[2])).floor(); | 86 var begin = (1e6 * double.parse(fields[2])).floor(); |
| 87 var duration = (1000 * double.parse(fields[3])).floor(); | 87 var duration = (1000 * double.parse(fields[3])).floor(); |
| 88 var end = begin + duration; | 88 var end = begin + duration; |
| 89 return new Interval<int>(begin, end); | 89 return new Interval<int>(begin, end); |
| 90 } | 90 } |
| 91 | 91 |
| 92 void main() { | 92 void main() { |
| 93 Timeline t = new Timeline(); | 93 Timeline t = new Timeline(); |
| 94 for (String line = stdin.readLineSync(); | 94 for (String line = stdin.readLineSync(); |
| 95 line != null; | 95 line != null; |
| 96 line = stdin.readLineSync()) { | 96 line = stdin.readLineSync()) { |
| 97 t.addPause(parseVerboseGCLine(line)); | 97 t.addPause(parseVerboseGCLine(line)); |
| 98 } | 98 } |
| 99 print('# window_size_ms, bounded_mutator_utilization'); | 99 print('# window_size_ms, bounded_mutator_utilization'); |
| 100 var minimumSeen = 1.0; | 100 var minimumSeen = 1.0; |
| 101 for (int w = t._run.length; | 101 for (int w = t._run.length; |
| 102 w > 1000 * MINIMUM_WINDOW_SIZE_MS; | 102 w > 1000 * MINIMUM_WINDOW_SIZE_MS; |
| 103 w = (w * WINDOW_STEP_FACTOR).floor()) { | 103 w = (w * WINDOW_STEP_FACTOR).floor()) { |
| 104 minimumSeen = min(minimumSeen, t.minUtilization(w)); | 104 minimumSeen = min(minimumSeen, t.minUtilization(w)); |
| 105 print('${w / 1000}, $minimumSeen'); | 105 print('${w / 1000}, $minimumSeen'); |
| 106 } | 106 } |
| 107 } | 107 } |
| OLD | NEW |