Skip to content

Commit 1a218c0

Browse files
jensjohaCommit Queue
authored andcommitted
[kernel/CFE] Dill extractor tool; CFE compile dir tool; fixes for stats
This CL adds two tools * A dill extractor tool which extracts the source files inside the dill to a new directory, trying to recrease the package config too so the sources can be compiled again. Thought as being useful for doing benchmarks between the CFE and the analyzer to make sure they look at the exact same source files. No more. No less. * A CFE compile entry point that compiles all files in a directory. Again thought as being useful to compare the CFE with the Analyzer. Additionally it introduces "--gcs=<int>" to `benchmarker.dart` so it can do multiple runs and do statistics on combined gc times. Usage example: ``` $ out/ReleaseX64/dart pkg/front_end/tool/compile.dart pkg/front_end/tool/compile.dart $ out/ReleaseX64/dart-sdk/bin/dart pkg/kernel/bin/dill_extractor.dart pkg/front_end/tool/compile.dart.dill /tmp/extracted_compile_dart_compile Done. Wrote 687 source files. $ out/ReleaseX64/dart-sdk/bin/dart compile aot-snapshot pkg/front_end/tool/compile_files_in_folders.dart Generated: [...]/pkg/front_end/tool/compile_files_in_folders.aot $ out/ReleaseX64/dart-sdk/bin/dart compile aot-snapshot pkg/analyzer_cli/bin/analyzer.dart Generated: [...]/pkg/analyzer_cli/bin/analyzer.aot $ time out/ReleaseX64/dart-sdk/bin/dartaotruntime pkg/front_end/tool/compile_files_in_folders.aot /tmp/extracted_compile_dart_compile/ Got 626 libraries. Finished in 0:00:03.496817 real 0m3.530s user 0m4.985s sys 0m0.257s $ time out/ReleaseX64/dart-sdk/bin/dartaotruntime pkg/analyzer_cli/bin/analyzer.aot /tmp/extracted_compile_dart_compile/ Analyzing /tmp/extracted_compile_dart_compile... warning • Target of URI doesn't exist: 'package:compiler/src/io/source_file.dart'. • package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart:5:16 • uri_does_not_exist_in_doc_import 1 warning found. real 0m8.479s user 0m9.997s sys 0m1.048s $ out/ReleaseX64/dart pkg/front_end/tool/benchmarker.dart --silent --iterations=10 --gcs=5 --snapshot=pkg/front_end/tool/compile_files_in_folders.aot --snapshot=pkg/analyzer_cli/bin/analyzer.aot --arguments="/tmp/extracted_compile_dart_compile/" Will now run 10 iterations with 2 snapshots. .............................. Comparing snapshot #1 (compile_files_in_folders.aot) with snapshot #2 (analyzer.aot) msec task-clock:u: 141.1012% +/- 1.5550% (6281.55 +/- 69.22) (4451.81 -> 10733.36) page-faults:u: 47.5414% +/- 0.7786% (45602.90 +/- 746.84) (95922.50 -> 141525.40) cycles:u: 119.3182% +/- 1.5751% (22131655652.90 +/- 292155654.08) (18548436164.50 -> 40680091817.40) instructions:u: 140.2463% +/- 0.0340% (30410953910.60 +/- 7375789.67) (21683959961.20 -> 52094913871.80) branch-misses:u: 97.9816% +/- 7.3049% (73071988.00 +/- 5447773.30) (74577266.40 -> 147649254.40) seconds time elapsed: 141.0789% +/- 1.5479% (6.28 +/- 0.07) (4.45 -> 10.74) seconds user: 124.4165% +/- 1.8322% (5.31 +/- 0.08) (4.26 -> 9.57) seconds sys: 521.0422% +/- 17.4291% (0.98 +/- 0.03) (0.19 -> 1.16) Comparing GC: Combined GC time: 63.8901% +/- 1.2946% (1008.76 +/- 20.44) (1578.90 -> 2587.66) ``` (note that benchmarker passes `--deterministic` and limits the run to one cpu, both of which (potentially) makes it slower --- which is why the stats say 4.45 s instead of ~3.53 s and 10.74 s instead of ~8.48 s) Change-Id: I785620ce40af11ca1f7b6c88a0ac863b2200f7d3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449180 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent 48cc23e commit 1a218c0

File tree

6 files changed

+312
-26
lines changed

6 files changed

+312
-26
lines changed

pkg/front_end/test/simple_stats.dart

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import 'dart:math' as math;
66

77
class SimpleTTestStat {
8-
static TTestResult ttest<E extends num>(List<E> a, List<E> b) {
9-
E aSum = a.reduce((value, element) => (value + element) as E);
10-
E bSum = b.reduce((value, element) => (value + element) as E);
8+
static TTestResult ttest(List<num> a, List<num> b) {
9+
num aSum = sum(a);
10+
num bSum = sum(b);
1111
int aCount = a.length;
1212
int bCount = b.length;
1313
double aMean = aSum / aCount;
@@ -41,18 +41,16 @@ class SimpleTTestStat {
4141
}
4242
}
4343

44-
static double average<E extends num>(List<E> data) {
45-
E sum = data.reduce((value, element) => (value + element) as E);
46-
return sum / data.length;
44+
static double average(List<num> data) {
45+
return sum(data) / data.length;
4746
}
4847

49-
static double variance<E extends num>(List<E> data) {
50-
E sum = data.reduce((value, element) => (value + element) as E);
48+
static double variance(List<num> data) {
5149
int count = data.length;
52-
double average = sum / count;
50+
double average = sum(data) / count;
5351

5452
double diffSquareSum = 0;
55-
for (E value in data) {
53+
for (num value in data) {
5654
double diff = value - average;
5755
double squared = diff * diff;
5856
diffSquareSum += squared;
@@ -62,6 +60,14 @@ class SimpleTTestStat {
6260
return variance;
6361
}
6462

63+
static num sum(List<num> data) {
64+
num result = 0;
65+
for (num value in data) {
66+
result += value;
67+
}
68+
return result;
69+
}
70+
6571
static double tTableTwoTails_0_05(int value) {
6672
// TODO: Maybe actually calculate this? I haven't looked that up.
6773
// These numbers are from google sheets "=TINV(0.05, value)"

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,7 @@ pieces
13241324
pipe
13251325
pkg
13261326
pkgs
1327+
placement
13271328
play
13281329
player
13291330
plugin

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ gave
388388
gc
389389
gcd
390390
gclient
391+
gcs
391392
ge
392393
gesture
393394
gi

pkg/front_end/tool/benchmarker.dart

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ void main(List<String> args) {
1616
bool silent = false;
1717
int iterations = 5;
1818
int core = 7;
19+
int gcRuns = 1;
1920
String? aotRuntime;
2021
String? checkFileSize;
2122
List<String> snapshots = [];
2223
List<String> arguments = [];
2324
for (String arg in args) {
2425
if (arg.startsWith("--iterations=")) {
2526
iterations = int.parse(arg.substring("--iterations=".length));
27+
} else if (arg.startsWith("--gcs=")) {
28+
gcRuns = int.parse(arg.substring("--gcs=".length));
2629
} else if (arg.startsWith("--core=")) {
2730
core = int.parse(arg.substring("--core=".length));
2831
} else if (arg.startsWith("--aotruntime")) {
@@ -59,6 +62,7 @@ void main(List<String> args) {
5962
checkFileSize,
6063
cacheBenchmarking: false,
6164
silent: silent,
65+
gcRuns: gcRuns,
6266
);
6367
if (doCacheBenchmarkingToo) {
6468
_doRun(
@@ -70,6 +74,7 @@ void main(List<String> args) {
7074
checkFileSize,
7175
cacheBenchmarking: true,
7276
silent: silent,
77+
gcRuns: gcRuns,
7378
);
7479
}
7580
}
@@ -83,16 +88,19 @@ void _doRun(
8388
String? checkFileSize, {
8489
required bool cacheBenchmarking,
8590
required bool silent,
91+
required int gcRuns,
8692
}) {
8793
print(
8894
"Will now run $iterations iterations with "
8995
"${snapshots.length} snapshots.",
9096
);
9197

9298
List<List<Map<String, num>>> runResults = [];
93-
List<GCInfo> gcInfos = [];
99+
List<List<GCInfo>> gcInfos = [];
94100
Warnings warnings = new Warnings();
95101
for (String snapshot in snapshots) {
102+
List<GCInfo> gcInfo = [];
103+
gcInfos.add(gcInfo);
96104
List<Map<String, num>> snapshotResults = [];
97105
runResults.add(snapshotResults);
98106
for (int iteration = 0; iteration < iterations; iteration++) {
@@ -118,11 +126,13 @@ void _doRun(
118126
snapshotResults.add(benchmarkRun);
119127
}
120128

121-
// Do a single GC run too.
122-
if (silent) stdout.write(".");
123-
gcInfos.add(
124-
_verboseGcRun(aotRuntime, snapshot, [], arguments, silent: true),
125-
);
129+
// Do GC runs too.
130+
for (int i = 0; i < gcRuns; i++) {
131+
if (silent) stdout.write(".");
132+
gcInfo.add(
133+
_verboseGcRun(aotRuntime, snapshot, [], arguments, silent: true),
134+
);
135+
}
126136
}
127137
stdout.write("\n\n");
128138

@@ -137,7 +147,20 @@ void _doRun(
137147
if (!_compare(firstSnapshotResults, compareToResults)) {
138148
print("No change.");
139149
}
140-
printGcDiff(gcInfos.first, gcInfos[i]);
150+
print("Comparing GC:");
151+
if (gcRuns >= 3) {
152+
if (!_compareSingle(
153+
gcInfos[i].map((gcInfo) => gcInfo.combinedTime).toList(),
154+
gcInfos[0].map((gcInfo) => gcInfo.combinedTime).toList(),
155+
"Combined GC time",
156+
)) {
157+
print("No change in combined time.");
158+
}
159+
} else {
160+
for (int gcNum = 0; gcNum < gcRuns; gcNum++) {
161+
printGcDiff(gcInfos[0][gcNum], gcInfos[i][gcNum]);
162+
}
163+
}
141164
}
142165

143166
if (warnings.scalingInEffect) {
@@ -213,19 +236,28 @@ bool _compare(List<Map<String, num>> from, List<Map<String, num>> to) {
213236
}
214237
}
215238
if (fromForCaption.isEmpty || toForCaption.isEmpty) continue;
216-
TTestResult stats = SimpleTTestStat.ttest(toForCaption, fromForCaption);
217-
if (stats.significant) {
218-
somethingWasSignificant = true;
219-
print(
220-
"$caption: ${stats.percentChangeIfSignificant(fractionDigits: 4)} "
221-
"(${stats.valueChangeIfSignificant(fractionDigits: 2)}) "
222-
"(${stats.meanChangeStringIfSignificant(fractionDigits: 2)})",
223-
);
224-
}
239+
somethingWasSignificant = _compareSingle(
240+
toForCaption,
241+
fromForCaption,
242+
caption,
243+
);
225244
}
226245
return somethingWasSignificant;
227246
}
228247

248+
bool _compareSingle(List<num> to, List<num> from, String caption) {
249+
TTestResult stats = SimpleTTestStat.ttest(to, from);
250+
if (stats.significant) {
251+
print(
252+
"$caption: ${stats.percentChangeIfSignificant(fractionDigits: 4)} "
253+
"(${stats.valueChangeIfSignificant(fractionDigits: 2)}) "
254+
"(${stats.meanChangeStringIfSignificant(fractionDigits: 2)})",
255+
);
256+
return true;
257+
}
258+
return false;
259+
}
260+
229261
List<num> _extractDataForCaption(String caption, List<Map<String, num>> data) {
230262
List<num> result = [];
231263
for (Map<String, num> entry in data) {
@@ -463,6 +495,10 @@ GCInfo parseVerboseGcText(List<String> stderrLines) {
463495
return new GCInfo(combinedTime, countWhat);
464496
}
465497

498+
void combinedGcDiff(List<GCInfo> prev, List<GCInfo> current) {
499+
prev.map((gcInfo) => gcInfo.combinedTime).toList();
500+
}
501+
466502
void printGcDiff(GCInfo prev, GCInfo current) {
467503
Set<String> allKeys = {...prev.countWhat.keys, ...current.countWhat.keys};
468504
bool printedAnything = false;
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'dart:io';
6+
7+
import 'package:_fe_analyzer_shared/src/messages/severity.dart';
8+
import 'package:front_end/src/api_prototype/compiler_options.dart' as api;
9+
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
10+
show IncrementalCompilerResult;
11+
import 'package:front_end/src/base/processed_options.dart';
12+
import 'package:front_end/src/compute_platform_binaries_location.dart'
13+
show computePlatformBinariesLocation;
14+
import 'package:front_end/src/base/compiler_context.dart';
15+
import 'package:front_end/src/base/incremental_compiler.dart';
16+
import 'package:kernel/target/targets.dart';
17+
import 'package:vm/modular/target/vm.dart';
18+
19+
import '../test/utils/io_utils.dart' show computeRepoDirUri;
20+
21+
final Uri repoDir = computeRepoDirUri();
22+
23+
Future<void> main(List<String> args) async {
24+
Stopwatch stopwatch = new Stopwatch()..start();
25+
await run(args);
26+
print("Finished in ${stopwatch.elapsed}");
27+
}
28+
29+
Future<void> run(List<String> args) async {
30+
api.CompilerOptions compilerOptions = getOptions();
31+
32+
ProcessedOptions options = new ProcessedOptions(options: compilerOptions);
33+
34+
Set<Uri> libUris = {};
35+
Set<Uri> packageConfigUris = {};
36+
for (String arg in args) {
37+
Uri dir = Uri.base.resolveUri(new Uri.file(arg));
38+
libUris.add(dir);
39+
while (!File.fromUri(
40+
dir.resolve(".dart_tool/package_config.json"),
41+
).existsSync()) {
42+
Uri newDir = dir.resolve("..");
43+
if (newDir != dir) {
44+
dir = newDir;
45+
} else {
46+
throw "Couldn't find package config for $arg";
47+
}
48+
}
49+
packageConfigUris.add(dir.resolve(".dart_tool/package_config.json"));
50+
}
51+
if (packageConfigUris.length != 1) throw "Didn't find unique package config.";
52+
53+
Uri packageConfigUri = packageConfigUris.first;
54+
if (!new File.fromUri(packageConfigUri).existsSync()) {
55+
throw "Couldn't find .dart_tool/package_config.json";
56+
}
57+
compilerOptions.packagesFileUri = packageConfigUri;
58+
59+
for (Uri uri in libUris) {
60+
List<FileSystemEntity> entities = new Directory.fromUri(
61+
uri,
62+
).listSync(recursive: true);
63+
for (FileSystemEntity entity in entities) {
64+
if (entity is File && entity.path.endsWith(".dart")) {
65+
options.inputs.add(entity.uri);
66+
}
67+
}
68+
}
69+
70+
IncrementalCompiler compiler = new IncrementalCompiler(
71+
new CompilerContext(options),
72+
);
73+
IncrementalCompilerResult result = await compiler.computeDelta();
74+
print("Got ${result.component.libraries.length} libraries.");
75+
}
76+
77+
api.CompilerOptions getOptions() {
78+
Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
79+
api.CompilerOptions options = new api.CompilerOptions()
80+
..sdkRoot = sdkRoot
81+
..compileSdk = false
82+
..target = new VmTarget(new TargetFlags())
83+
..librariesSpecificationUri = repoDir.resolve("sdk/lib/libraries.json")
84+
..omitPlatform = true
85+
..onDiagnostic = (api.CfeDiagnosticMessage message) {
86+
if (message.severity == CfeSeverity.error) {
87+
print(message.plainTextFormatted.join('\n'));
88+
exitCode = 1;
89+
}
90+
}
91+
..environmentDefines = const {};
92+
return options;
93+
}

0 commit comments

Comments
 (0)