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

Unified Diff: pkg/front_end/tool/perf.dart

Issue 2602003002: fe: minor change to benchmarks to match what the runners expect (Closed)
Patch Set: . Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/tool/perf.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/tool/perf.dart
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index 7cd3a49126cf372e330c749a62a0dfbdf9d91f00..c994047d6fe6a564b73552df9c2256e2b8346b08 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -37,95 +37,61 @@ main(List<String> args) async {
print('usage: perf.dart <bench-id> <entry.dart>');
exit(1);
}
- var totalTimer = new Stopwatch()..start();
var bench = args[0];
var entryUri = Uri.base.resolve(args[1]);
await setup(entryUri);
+ Set<Source> files = scanReachableFiles(entryUri);
var handlers = {
- 'scan': () async {
- Set<Source> files = scanReachableFiles(entryUri);
- // TODO(sigmund): replace the warmup with instrumented snapshots.
- for (int i = 0; i < 10; i++) scanFiles(files);
- },
- 'parse': () async {
- Set<Source> files = scanReachableFiles(entryUri);
- // TODO(sigmund): replace the warmup with instrumented snapshots.
- for (int i = 0; i < 10; i++) parseFiles(files);
- },
+ 'scan': () async => scanFiles(files),
+ 'parse': () async => parseFiles(files),
'kernel_gen_e2e': () async {
- // TODO(sigmund): remove. This is used to compute the input size, we
- // should extract input size from frontend instead.
- scanReachableFiles(entryUri);
- // TODO(sigmund): replace this warmup. Note that for very large programs,
- // the GC pressure on the VM seems to make this worse with time (maybe we
- // are leaking memory?). That's why we run it twice and not 10 times.
- for (int i = 0; i < 2; i++) {
- await generateKernel(entryUri, useSdkSummary: false);
- }
+ await generateKernel(entryUri, useSdkSummary: false);
},
'kernel_gen_e2e_sum': () async {
- // TODO(sigmund): remove. This is incorrect since it includes sizes for
- // files that will not be loaded when using summaries. We need to extract
- // input size from frontend instead.
- scanReachableFiles(entryUri);
- // TODO(sigmund): replace this warmup. Note that for very large programs,
- // the GC pressure on the VM seems to make this worse with time (maybe we
- // are leaking memory?). That's why we run it twice and not 10 times.
- for (int i = 0; i < 2; i++) {
- await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
- }
- },
- 'unlinked_summarize': () async {
- Set<Source> files = scanReachableFiles(entryUri);
- // TODO(sigmund): replace the warmup with instrumented snapshots.
- for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files);
- },
- 'prelinked_summarize': () async {
- Set<Source> files = scanReachableFiles(entryUri);
- // TODO(sigmund): replace the warmup with instrumented snapshots.
- for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files);
+ await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
},
- 'linked_summarize': () async {
- Set<Source> files = scanReachableFiles(entryUri);
- // TODO(sigmund): replace the warmup with instrumented snapshots.
- for (int i = 0; i < 10; i++) linkedSummarizeFiles(files);
- }
+ 'unlinked_summarize': () async => summarize(files),
+ 'prelinked_summarize': () async => summarize(files, prelink: true),
+ 'linked_summarize': () async => summarize(files, link: true),
};
var handler = handlers[bench];
if (handler == null) {
- // TODO(sigmund): implement the remaining benchmarks.
print('unsupported bench-id: $bench. Please specify one of the following: '
'${handlers.keys.join(", ")}');
exit(1);
}
- await handler();
- totalTimer.stop();
- report("total", totalTimer.elapsedMicroseconds);
+ // TODO(sigmund): replace the warmup with instrumented snapshots.
+ int iterations = bench.contains('kernel_gen') ? 2 : 10;
+ for (int i = 0; i < iterations; i++) {
+ var totalTimer = new Stopwatch()..start();
+ print('== iteration $i');
+ await handler();
+ totalTimer.stop();
+ report("total", totalTimer.elapsedMicroseconds);
+ }
+
}
/// Cumulative time spent parsing.
Stopwatch parseTimer = new Stopwatch();
-/// Cumulative time spent prelinking summaries.
-Stopwatch prelinkSummaryTimer = new Stopwatch();
+/// Cumulative time spent building unlinked summaries.
+Stopwatch unlinkedSummarizeTimer = new Stopwatch();
/// Cumulative time spent scanning.
Stopwatch scanTimer = new Stopwatch();
-/// Cumulative total number of chars scanned.
-int scanTotalChars = 0;
+/// Size of all sources.
+int inputSize = 0;
/// Factory to load and resolve app, packages, and sdk sources.
SourceFactory sources;
-/// Cumulative time spent building unlinked summaries.
-Stopwatch unlinkedSummarizeTimer = new Stopwatch();
-
/// Add to [files] all sources reachable from [start].
void collectSources(Source start, Set<Source> files) {
if (!files.add(start)) return;
@@ -140,6 +106,10 @@ void collectSources(Source start, Set<Source> files) {
Future<Program> generateKernel(Uri entryUri,
{bool useSdkSummary: false, bool compileSdk: true}) async {
+ // TODO(sigmund): this is here only to compute the input size,
+ // we should extract the input size from the frontend instead.
+ scanReachableFiles(entryUri);
+
var dartkTimer = new Stopwatch()..start();
// TODO(sigmund): add a constructor with named args to compiler options.
var options = new CompilerOptions()
@@ -163,9 +133,9 @@ Future<Program> generateKernel(Uri entryUri,
}
/// Generates unlinkmed summaries for all files in [files], and returns them in
-/// an [UnlinkedSummaries] container.
-UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
- var unlinkedSummaries = new UnlinkedSummaries();
+/// an [_UnlinkedSummaries] container.
+_UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
+ var unlinkedSummaries = new _UnlinkedSummaries();
for (var source in files) {
unlinkedSummaries.summariesByUri[source.uri.toString()] =
unlinkedSummarize(source);
@@ -175,42 +145,40 @@ UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
/// Produces linked summaries for every file in [files] and reports the time
Paul Berry 2017/01/03 17:58:34 Doc comment is no longer accurate.
Siggi Cherem (dart-lang) 2017/01/04 00:01:04 Done.
/// spent doing so.
-void linkedSummarizeFiles(Set<Source> files) {
- // The code below will record again how many chars are scanned and how long it
- // takes to scan them, even though we already did so in [scanReachableFiles].
- // Recording and reporting this twice is unnecessary, but we do so for now to
- // validate that the results are consistent.
+void summarize(Set<Source> files, {bool prelink: false, bool link: false}) {
scanTimer = new Stopwatch();
- var old = scanTotalChars;
- scanTotalChars = 0;
parseTimer = new Stopwatch();
unlinkedSummarizeTimer = new Stopwatch();
var unlinkedSummaries = generateUnlinkedSummaries(files);
- prelinkSummaryTimer = new Stopwatch();
- Map<String, LinkedLibraryBuilder> prelinkedLibraries =
- prelinkSummaries(files, unlinkedSummaries);
- var linkTimer = new Stopwatch()..start();
- LinkedLibrary getDependency(String uri) {
- // getDependency should never be called because all dependencies are present
- // in [prelinkedLibraries].
- print('Warning: getDependency called for: $uri');
- return null;
- }
-
- bool strong = true;
- relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit, strong);
- linkTimer.stop();
-
- if (old != scanTotalChars) print('input size changed? ${old} chars');
report("scan", scanTimer.elapsedMicroseconds);
report("parse", parseTimer.elapsedMicroseconds);
- report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
+ report('unlink extract', unlinkedSummarizeTimer.elapsedMicroseconds);
Paul Berry 2017/01/03 17:58:34 I don't really have strong feelings about nomencla
Siggi Cherem (dart-lang) 2017/01/04 00:01:04 In all honestly, I'm not convinced about "extract"
Paul Berry 2017/01/04 13:55:43 In that case I'd prefer (b), on the theory that tr
report(
- 'unlinked summarize + parse',
+ 'unlinked_summarize',
unlinkedSummarizeTimer.elapsedMicroseconds +
parseTimer.elapsedMicroseconds);
- report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
- report('link', linkTimer.elapsedMicroseconds);
+
+ if (prelink || link) {
+ var prelinkTimer = new Stopwatch()..start();
+ var prelinkedLibraries = prelinkSummaries(files, unlinkedSummaries);
+ prelinkTimer.stop();
+ report('prelinked_summarize', prelinkTimer.elapsedMicroseconds);
+
+ if (link) {
+ var linkTimer = new Stopwatch()..start();
+ LinkedLibrary getDependency(String uri) {
+ // getDependency should never be called because all dependencies are
+ // present in [prelinkedLibraries].
+ print('Warning: getDependency called for: $uri');
+ return null;
+ }
+
+ relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit,
+ true /*strong*/);
+ linkTimer.stop();
+ report('linked_summarize', linkTimer.elapsedMicroseconds);
+ }
+ }
}
/// Uses the diet-parser to parse only directives in [source].
@@ -222,20 +190,12 @@ CompilationUnit parseDirectives(Source source) {
/// Parses every file in [files] and reports the time spent doing so.
void parseFiles(Set<Source> files) {
- // The code below will record again how many chars are scanned and how long it
- // takes to scan them, even though we already did so in [scanReachableFiles].
- // Recording and reporting this twice is unnecessary, but we do so for now to
- // validate that the results are consistent.
scanTimer = new Stopwatch();
- var old = scanTotalChars;
- scanTotalChars = 0;
parseTimer = new Stopwatch();
for (var source in files) {
parseFull(source);
}
- // Report size and scanning time again. See discussion above.
- if (old != scanTotalChars) print('input size changed? ${old} chars');
report("scan", scanTimer.elapsedMicroseconds);
report("parse", parseTimer.elapsedMicroseconds);
}
@@ -250,74 +210,40 @@ CompilationUnit parseFull(Source source) {
return unit;
}
-/// Produces prelinked summaries for every file in [files] and reports the time
-/// spent doing so.
-void prelinkedSummarizeFiles(Set<Source> files) {
- // The code below will record again how many chars are scanned and how long it
- // takes to scan them, even though we already did so in [scanReachableFiles].
- // Recording and reporting this twice is unnecessary, but we do so for now to
- // validate that the results are consistent.
- scanTimer = new Stopwatch();
- var old = scanTotalChars;
- scanTotalChars = 0;
- parseTimer = new Stopwatch();
- unlinkedSummarizeTimer = new Stopwatch();
- var unlinkedSummaries = generateUnlinkedSummaries(files);
- prelinkSummaryTimer = new Stopwatch();
- prelinkSummaries(files, unlinkedSummaries);
-
- if (old != scanTotalChars) print('input size changed? ${old} chars');
- report("scan", scanTimer.elapsedMicroseconds);
- report("parse", parseTimer.elapsedMicroseconds);
- report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
- report(
- 'unlinked summarize + parse',
- unlinkedSummarizeTimer.elapsedMicroseconds +
- parseTimer.elapsedMicroseconds);
- report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
-}
-
/// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
/// their unlinked summaries.
///
/// The return value is suitable for passing to the summary linker.
Map<String, LinkedLibraryBuilder> prelinkSummaries(
- Set<Source> files, UnlinkedSummaries unlinkedSummaries) {
- prelinkSummaryTimer.start();
- Set<String> libraryUris =
- files.map((source) => source.uri.toString()).toSet();
+ Set<Source> files, _UnlinkedSummaries unlinkedSummaries) {
+ Set<String> libraryUris = files.map((source) => '${source.uri}').toSet();
String getDeclaredVariable(String s) => null;
var prelinkedLibraries =
setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
- prelinkSummaryTimer.stop();
return prelinkedLibraries;
}
/// Report that metric [name] took [time] micro-seconds to process
-/// [scanTotalChars] characters.
+/// [inputSize] characters.
void report(String name, int time) {
var sb = new StringBuffer();
- sb.write('$name: $time us, ${time ~/ 1000} ms');
- sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
+ var padding = " " * (20 - name.length);
+ sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
+ sb.write(', ${time * 1000 ~/ inputSize} ns/char');
print('$sb');
}
/// Scans every file in [files] and reports the time spent doing so.
void scanFiles(Set<Source> files) {
- // The code below will record again how many chars are scanned and how long it
- // takes to scan them, even though we already did so in [scanReachableFiles].
- // Recording and reporting this twice is unnecessary, but we do so for now to
- // validate that the results are consistent.
+ // `tokenize` records how many chars are scanned and how long it takes to scan
+ // them. As this function is called repeatedly when running as a benchmark, we
+ // make sure to clear the data and compute it again every time.
scanTimer = new Stopwatch();
- var old = scanTotalChars;
- scanTotalChars = 0;
for (var source in files) {
tokenize(source);
}
- // Report size and scanning time again. See discussion above.
- if (old != scanTotalChars) print('input size changed? ${old} chars');
report("scan", scanTimer.elapsedMicroseconds);
}
@@ -348,7 +274,8 @@ Set<Source> scanReachableFiles(Uri entryUri) {
loadTimer.stop();
- print('input size: ${scanTotalChars} chars');
+ for (var s in files) inputSize += s.contents.data.length;
+ print('input size: ${inputSize} chars');
var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
report("load", loadTime);
report("scan", scanTimer.elapsedMicroseconds);
@@ -372,11 +299,9 @@ Future setup(Uri entryUri) async {
/// Scan [source] and return the first token produced by the scanner.
Token tokenize(Source source) {
scanTimer.start();
- var contents = source.contents.data;
- scanTotalChars += contents.length;
// TODO(sigmund): is there a way to scan from a random-access-file without
// first converting to String?
- var scanner = new _Scanner(contents);
+ var scanner = new _Scanner(source.contents.data);
var token = scanner.tokenize();
scanTimer.stop();
return token;
@@ -390,32 +315,8 @@ UnlinkedUnitBuilder unlinkedSummarize(Source source) {
return unlinkedUnit;
}
-/// Produces unlinked summaries for every file in [files] and reports the time
-/// spent doing so.
-void unlinkedSummarizeFiles(Set<Source> files) {
- // The code below will record again how many chars are scanned and how long it
- // takes to scan them, even though we already did so in [scanReachableFiles].
- // Recording and reporting this twice is unnecessary, but we do so for now to
- // validate that the results are consistent.
- scanTimer = new Stopwatch();
- var old = scanTotalChars;
- scanTotalChars = 0;
- parseTimer = new Stopwatch();
- unlinkedSummarizeTimer = new Stopwatch();
- generateUnlinkedSummaries(files);
-
- if (old != scanTotalChars) print('input size changed? ${old} chars');
- report("scan", scanTimer.elapsedMicroseconds);
- report("parse", parseTimer.elapsedMicroseconds);
- report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
- report(
- 'unlinked summarize + parse',
- unlinkedSummarizeTimer.elapsedMicroseconds +
- parseTimer.elapsedMicroseconds);
-}
-
/// Simple container for a mapping from URI string to an unlinked summary.
-class UnlinkedSummaries {
+class _UnlinkedSummaries {
final summariesByUri = <String, UnlinkedUnit>{};
/// Get the unlinked summary for the given URI, and report a warning if it
« no previous file with comments | « pkg/compiler/tool/perf.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698