Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Commit

Permalink
Create perf stat subprocess and attach it to the current benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
whesse committed Feb 8, 2024
1 parent 73f42b0 commit a9858d9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
7 changes: 0 additions & 7 deletions lib/src/benchmark_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ class BenchmarkBase {
/// Not measured teardown code executed after the benchmark runs.
void teardown() {}

/// Not measured code run just before starting the timed runs
void beforeTimedRuns() {}

/// Not measured code run just after the timed runs finish.
/// Receives the total number of iterations run.
void afterTimedRuns(int totalIterations) {}

/// Measures the score for this benchmark by executing it enough times
/// to reach [minimumMillis].
Expand Down
38 changes: 36 additions & 2 deletions lib/src/perf_benchmark_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'benchmark_base.dart';
Expand All @@ -20,10 +21,22 @@ class PerfBenchmarkBase extends BenchmarkBase {
late Process perfProcess;

Future<void> _startPerfStat() async {
// TODO: Create these fifos here instead of getting them through env variables.
perfControlFifo = Platform.environment[perfControlFifoVariable];
perfControlAck = Platform.environment[perfControlAckVariable];
print(perfControlFifo);
if (perfControlFifo != null) {
perfProcess = await Process.start('perf', [
'stat',
'--delay',
'-1',
'--control',
'fifo:$perfControlFifo,$perfControlAck',
'-j',
'-p',
'$pid'
]);
await Future<void>.delayed(const Duration(seconds: 2));

openedFifo = File(perfControlFifo!).openSync(mode: FileMode.writeOnly);
if (perfControlAck != null) {
openedAck = File(perfControlAck!).openSync();
Expand All @@ -43,7 +56,15 @@ class PerfBenchmarkBase extends BenchmarkBase {
_waitForAck();
openedAck.closeSync();
}
emitter.emit('$name.totalIterations', totalIterations.toDouble());
perfProcess.kill(ProcessSignal.sigint);
final lines =
utf8.decoder.bind(perfProcess.stderr).transform(const LineSplitter());
final events = [
await for (final line in lines)
if (line.startsWith('{"counter-value" : '))
jsonDecode(line) as Map<String, dynamic>
];
_reportPerfStats(events, totalIterations);
}
}

Expand Down Expand Up @@ -73,4 +94,17 @@ class PerfBenchmarkBase extends BenchmarkBase {
print('Ack was $ack');
}
}

void _reportPerfStats(List<Map<String, dynamic>> events, int iterations) {
for (final {'event': String event, 'counter-value': String counterString}
in events) {
final metric =
{'cycles:u': 'CpuCycles', 'page-faults:u': 'MajorPageFaults'}[event];
if (metric != null) {
emitter.emit(
'$name($metric)', double.parse(counterString) / iterations);
}
}
emitter.emit('$name.totalIterations', iterations.toDouble());
}
}

0 comments on commit a9858d9

Please sign in to comment.