Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 the V8 project authors. All rights reserved. | 2 # Copyright 2014 the V8 project authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """ | 6 """ |
| 7 Performance runner for d8. | 7 Performance runner for d8. |
| 8 | 8 |
| 9 Call e.g. with tools/run-benchmarks.py --arch ia32 some_suite.json | 9 Call e.g. with tools/run-benchmarks.py --arch ia32 some_suite.json |
| 10 | 10 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 "android_ia32", | 106 "android_ia32", |
| 107 "arm", | 107 "arm", |
| 108 "ia32", | 108 "ia32", |
| 109 "mips", | 109 "mips", |
| 110 "mipsel", | 110 "mipsel", |
| 111 "nacl_ia32", | 111 "nacl_ia32", |
| 112 "nacl_x64", | 112 "nacl_x64", |
| 113 "x64", | 113 "x64", |
| 114 "arm64"] | 114 "arm64"] |
| 115 | 115 |
| 116 GENERIC_RESULTS_RE = re.compile( | |
| 117 r"^Trace\(([^\)]+)\), Result\(([^\)]+)\), StdDev\(([^\)]+)\)$") | |
| 116 | 118 |
| 117 class Results(object): | 119 class Results(object): |
| 118 """Place holder for result traces.""" | 120 """Place holder for result traces.""" |
| 119 def __init__(self, traces=None, errors=None): | 121 def __init__(self, traces=None, errors=None): |
| 120 self.traces = traces or [] | 122 self.traces = traces or [] |
| 121 self.errors = errors or [] | 123 self.errors = errors or [] |
| 122 | 124 |
| 123 def ToDict(self): | 125 def ToDict(self): |
| 124 return {"traces": self.traces, "errors": self.errors} | 126 return {"traces": self.traces, "errors": self.errors} |
| 125 | 127 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 "results": self.results, | 244 "results": self.results, |
| 243 "stddev": self.stddev, | 245 "stddev": self.stddev, |
| 244 }], self.errors) | 246 }], self.errors) |
| 245 | 247 |
| 246 | 248 |
| 247 class Runnable(Graph): | 249 class Runnable(Graph): |
| 248 """Represents a runnable benchmark suite definition (i.e. has a main file). | 250 """Represents a runnable benchmark suite definition (i.e. has a main file). |
| 249 """ | 251 """ |
| 250 @property | 252 @property |
| 251 def main(self): | 253 def main(self): |
| 252 return self._suite["main"] | 254 return self._suite.get("main", "") |
| 253 | 255 |
| 254 def ChangeCWD(self, suite_path): | 256 def ChangeCWD(self, suite_path): |
| 255 """Changes the cwd to to path defined in the current graph. | 257 """Changes the cwd to to path defined in the current graph. |
| 256 | 258 |
| 257 The benchmarks are supposed to be relative to the suite configuration. | 259 The benchmarks are supposed to be relative to the suite configuration. |
| 258 """ | 260 """ |
| 259 suite_dir = os.path.abspath(os.path.dirname(suite_path)) | 261 suite_dir = os.path.abspath(os.path.dirname(suite_path)) |
| 260 bench_dir = os.path.normpath(os.path.join(*self.path)) | 262 bench_dir = os.path.normpath(os.path.join(*self.path)) |
| 261 os.chdir(os.path.join(suite_dir, bench_dir)) | 263 os.chdir(os.path.join(suite_dir, bench_dir)) |
| 262 | 264 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 282 def __init__(self, suite, parent, arch): | 284 def __init__(self, suite, parent, arch): |
| 283 super(RunnableTrace, self).__init__(suite, parent, arch) | 285 super(RunnableTrace, self).__init__(suite, parent, arch) |
| 284 | 286 |
| 285 def Run(self, runner): | 287 def Run(self, runner): |
| 286 """Iterates over several runs and handles the output.""" | 288 """Iterates over several runs and handles the output.""" |
| 287 for stdout in runner(): | 289 for stdout in runner(): |
| 288 self.ConsumeOutput(stdout) | 290 self.ConsumeOutput(stdout) |
| 289 return self.GetResults() | 291 return self.GetResults() |
| 290 | 292 |
| 291 | 293 |
| 294 class RunnableGeneric(Runnable): | |
| 295 """Represents a runnable benchmark suite definition with generic traces.""" | |
| 296 def __init__(self, suite, parent, arch): | |
| 297 super(RunnableGeneric, self).__init__(suite, parent, arch) | |
| 298 | |
| 299 def Run(self, runner): | |
| 300 """Iterates over several runs and handles the output.""" | |
| 301 traces = {} | |
| 302 for stdout in runner(): | |
| 303 for line in stdout.strip().splitlines(): | |
| 304 match = GENERIC_RESULTS_RE.match(line) | |
| 305 if match: | |
| 306 trace = match.group(1) | |
| 307 result = match.group(2) | |
| 308 stddev = match.group(3) | |
| 309 trace_result = traces.setdefault(trace, Results([{ | |
| 310 "graphs": self.graphs + [trace], | |
| 311 "units": self.units, | |
| 312 "results": [], | |
| 313 "stddev": "", | |
| 314 }], [])) | |
| 315 trace_result.traces[0]["results"].append(result) | |
| 316 trace_result.traces[0]["stddev"] = stddev | |
|
Michael Achenbach
2014/08/22 14:41:26
Note: Having multiple reruns by the driver and a s
| |
| 317 | |
| 318 return reduce(lambda r, t: r + t, traces.itervalues(), Results()) | |
| 319 | |
| 320 | |
| 292 def MakeGraph(suite, arch, parent): | 321 def MakeGraph(suite, arch, parent): |
| 293 """Factory method for making graph objects.""" | 322 """Factory method for making graph objects.""" |
| 294 if isinstance(parent, Runnable): | 323 if isinstance(parent, Runnable): |
| 295 # Below a runnable can only be traces. | 324 # Below a runnable can only be traces. |
| 296 return Trace(suite, parent, arch) | 325 return Trace(suite, parent, arch) |
| 297 elif suite.get("main"): | 326 elif suite.get("main"): |
| 298 # A main file makes this graph runnable. | 327 # A main file makes this graph runnable. |
| 299 if suite.get("benchmarks"): | 328 if suite.get("benchmarks"): |
| 300 # This graph has subbenchmarks (traces). | 329 # This graph has subbenchmarks (traces). |
| 301 return Runnable(suite, parent, arch) | 330 return Runnable(suite, parent, arch) |
| 302 else: | 331 else: |
| 303 # This graph has no subbenchmarks, it's a leaf. | 332 # This graph has no subbenchmarks, it's a leaf. |
| 304 return RunnableTrace(suite, parent, arch) | 333 return RunnableTrace(suite, parent, arch) |
| 334 elif suite.get("generic"): | |
| 335 # This is a generic suite definition. It is either a runnable executable | |
| 336 # or has a main js file. | |
| 337 return RunnableGeneric(suite, parent, arch) | |
| 305 elif suite.get("benchmarks"): | 338 elif suite.get("benchmarks"): |
| 306 # This is neither a leaf nor a runnable. | 339 # This is neither a leaf nor a runnable. |
| 307 return Graph(suite, parent, arch) | 340 return Graph(suite, parent, arch) |
| 308 else: # pragma: no cover | 341 else: # pragma: no cover |
| 309 raise Exception("Invalid benchmark suite configuration.") | 342 raise Exception("Invalid benchmark suite configuration.") |
| 310 | 343 |
| 311 | 344 |
| 312 def BuildGraphs(suite, arch, parent=None): | 345 def BuildGraphs(suite, arch, parent=None): |
| 313 """Builds a tree structure of graph objects that corresponds to the suite | 346 """Builds a tree structure of graph objects that corresponds to the suite |
| 314 configuration. | 347 configuration. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 | 445 |
| 413 if options.json_test_results: | 446 if options.json_test_results: |
| 414 results.WriteToFile(options.json_test_results) | 447 results.WriteToFile(options.json_test_results) |
| 415 else: # pragma: no cover | 448 else: # pragma: no cover |
| 416 print results | 449 print results |
| 417 | 450 |
| 418 return min(1, len(results.errors)) | 451 return min(1, len(results.errors)) |
| 419 | 452 |
| 420 if __name__ == "__main__": # pragma: no cover | 453 if __name__ == "__main__": # pragma: no cover |
| 421 sys.exit(Main(sys.argv[1:])) | 454 sys.exit(Main(sys.argv[1:])) |
| OLD | NEW |