Skip to content

Commit 2ebd7f0

Browse files
author
Jonah Williams
authored
[Impeller] measure GPU memory usage. (#144575)
Framework side to flutter/engine#51187 Part of flutter/flutter#144617
1 parent 0df2200 commit 2ebd7f0

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

dev/devicelab/lib/tasks/perf_tests.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,10 +1451,16 @@ class PerfTest {
14511451
if (data['120hz_frame_percentage'] != null) '120hz_frame_percentage',
14521452
if (data['illegal_refresh_rate_frame_count'] != null) 'illegal_refresh_rate_frame_count',
14531453
if (recordGPU) ...<String>[
1454+
// GPU Frame Time.
14541455
if (data['average_gpu_frame_time'] != null) 'average_gpu_frame_time',
14551456
if (data['90th_percentile_gpu_frame_time'] != null) '90th_percentile_gpu_frame_time',
14561457
if (data['99th_percentile_gpu_frame_time'] != null) '99th_percentile_gpu_frame_time',
14571458
if (data['worst_gpu_frame_time'] != null) 'worst_gpu_frame_time',
1459+
// GPU Memory.
1460+
if (data['average_gpu_memory_mb'] != null) 'average_gpu_memory_mb',
1461+
if (data['90th_percentile_gpu_memory_mb'] != null) '90th_percentile_gpu_memory_mb',
1462+
if (data['99th_percentile_gpu_memory_mb'] != null) '99th_percentile_gpu_memory_mb',
1463+
if (data['worst_gpu_memory_mb'] != null) 'worst_gpu_memory_mb',
14581464
]
14591465
],
14601466
);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'percentile_utils.dart';
6+
import 'timeline.dart';
7+
8+
/// Summarizes GPU/Device Memory allocations performed by Impeller.
9+
class GPUMemorySumarizer {
10+
/// Creates a RasterCacheSummarizer given the timeline events.
11+
GPUMemorySumarizer(List<TimelineEvent> gpuEvents) {
12+
for (final TimelineEvent event in gpuEvents) {
13+
final Object? value = event.arguments!['MemoryBudgetUsageMB'];
14+
if (value is String) {
15+
final double? parsedValue = double.tryParse(value);
16+
if (parsedValue != null) {
17+
_memoryMB.add(parsedValue);
18+
}
19+
}
20+
}
21+
}
22+
23+
/// Whether or not this event is a GPU allocation event.
24+
static const Set<String> kMemoryEvents = <String>{'AllocatorVK'};
25+
26+
final List<double> _memoryMB = <double>[];
27+
28+
/// Computes the average GPU memory allocated.
29+
double computeAverageMemoryUsage() => _computeAverage(_memoryMB);
30+
31+
/// The [percentile]-th percentile GPU memory allocated.
32+
double computePercentileMemoryUsage(double percentile) {
33+
if (_memoryMB.isEmpty) {
34+
return 0;
35+
}
36+
return findPercentile(_memoryMB, percentile);
37+
}
38+
39+
/// Compute the worst allocation quantity recorded.
40+
double computeWorstMemoryUsage() => _computeWorst(_memoryMB);
41+
42+
static double _computeAverage(List<double> values) {
43+
if (values.isEmpty) {
44+
return 0;
45+
}
46+
47+
double total = 0;
48+
for (final double data in values) {
49+
total += data;
50+
}
51+
return total / values.length;
52+
}
53+
54+
static double _computeWorst(List<double> values) {
55+
if (values.isEmpty) {
56+
return 0;
57+
}
58+
59+
values.sort();
60+
return values.last;
61+
}
62+
}

packages/flutter_driver/lib/src/driver/timeline_summary.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'common.dart';
1212
import 'frame_request_pending_latency_summarizer.dart';
1313
import 'gc_summarizer.dart';
1414
import 'gpu_sumarizer.dart';
15+
import 'memory_summarizer.dart';
1516
import 'percentile_utils.dart';
1617
import 'profiling_summarizer.dart';
1718
import 'raster_cache_summarizer.dart';
@@ -277,6 +278,7 @@ class TimelineSummary {
277278
final RefreshRateSummary refreshRateSummary = RefreshRateSummary(vsyncEvents: _extractNamedEvents(kUIThreadVsyncProcessEvent));
278279
final FrameRequestPendingLatencySummarizer frameRequestPendingLatencySummarizer = _frameRequestPendingLatencySummarizer();
279280
final GpuSumarizer gpuSummarizer = _gpuSumarizer();
281+
final GPUMemorySumarizer memorySumarizer = _memorySummarizer();
280282

281283
final Map<String, dynamic> timelineSummary = <String, dynamic>{
282284
'average_frame_build_time_millis': computeAverageFrameBuildTimeMillis(),
@@ -342,6 +344,10 @@ class TimelineSummary {
342344
'90th_percentile_gpu_frame_time': gpuSummarizer.computePercentileGPUTime(90.0),
343345
'99th_percentile_gpu_frame_time': gpuSummarizer.computePercentileGPUTime(99.0),
344346
'worst_gpu_frame_time': gpuSummarizer.computeWorstGPUTime(),
347+
'average_gpu_memory_mb': memorySumarizer.computeAverageMemoryUsage(),
348+
'90th_percentile_gpu_memory_mb': memorySumarizer.computePercentileMemoryUsage(90.0),
349+
'99th_percentile_gpu_memory_mb': memorySumarizer.computePercentileMemoryUsage(99.0),
350+
'worst_gpu_memory_mb': memorySumarizer.computeWorstMemoryUsage(),
345351
};
346352

347353
timelineSummary.addAll(profilingSummary);
@@ -501,4 +507,6 @@ class TimelineSummary {
501507
GCSummarizer _gcSummarizer() => GCSummarizer.fromEvents(_extractEventsWithNames(kGCRootEvents));
502508

503509
GpuSumarizer _gpuSumarizer() => GpuSumarizer(_extractEventsWithNames(GpuSumarizer.kGpuEvents));
510+
511+
GPUMemorySumarizer _memorySummarizer() => GPUMemorySumarizer(_extractEventsWithNames(GPUMemorySumarizer.kMemoryEvents));
504512
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter_driver/flutter_driver.dart';
6+
import 'package:flutter_driver/src/driver/memory_summarizer.dart';
7+
8+
import '../common.dart';
9+
10+
TimelineEvent newGPUTraceEvent(double ms) => TimelineEvent(<String, dynamic>{
11+
'name': 'AllocatorVK',
12+
'ph': 'b',
13+
'args': <String, String>{
14+
'MemoryBudgetUsageMB': ms.toString()
15+
},
16+
});
17+
18+
void main() {
19+
test('Can process GPU memory usage times.', () {
20+
final GPUMemorySumarizer summarizer = GPUMemorySumarizer(<TimelineEvent>[
21+
newGPUTraceEvent(1024),
22+
newGPUTraceEvent(1024),
23+
newGPUTraceEvent(512),
24+
newGPUTraceEvent(2048),
25+
]);
26+
27+
expect(summarizer.computeAverageMemoryUsage(), closeTo(1152, 0.1));
28+
expect(summarizer.computePercentileMemoryUsage(50.0), closeTo(1024, 0.1));
29+
expect(summarizer.computeWorstMemoryUsage(), 2048);
30+
});
31+
}

packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,10 @@ void main() {
532532
'90th_percentile_gpu_frame_time': 0,
533533
'99th_percentile_gpu_frame_time': 0,
534534
'worst_gpu_frame_time': 0,
535+
'average_gpu_memory_mb': 0,
536+
'90th_percentile_gpu_memory_mb': 0,
537+
'99th_percentile_gpu_memory_mb': 0,
538+
'worst_gpu_memory_mb': 0,
535539
},
536540
);
537541
});
@@ -667,6 +671,10 @@ void main() {
667671
'90th_percentile_gpu_frame_time': 0,
668672
'99th_percentile_gpu_frame_time': 0,
669673
'worst_gpu_frame_time': 0,
674+
'average_gpu_memory_mb': 0,
675+
'90th_percentile_gpu_memory_mb': 0,
676+
'99th_percentile_gpu_memory_mb': 0,
677+
'worst_gpu_memory_mb': 0,
670678
});
671679
});
672680
});

0 commit comments

Comments
 (0)