mirror of
https://github.com/flutter/flutter
synced 2024-07-16 10:29:14 +00:00
[Impeller] measure GPU memory usage. (#144575)
Framework side to https://github.com/flutter/engine/pull/51187 Part of https://github.com/flutter/flutter/issues/144617
This commit is contained in:
parent
0df2200b80
commit
2ebd7f0d55
|
@ -1451,10 +1451,16 @@ class PerfTest {
|
|||
if (data['120hz_frame_percentage'] != null) '120hz_frame_percentage',
|
||||
if (data['illegal_refresh_rate_frame_count'] != null) 'illegal_refresh_rate_frame_count',
|
||||
if (recordGPU) ...<String>[
|
||||
// GPU Frame Time.
|
||||
if (data['average_gpu_frame_time'] != null) 'average_gpu_frame_time',
|
||||
if (data['90th_percentile_gpu_frame_time'] != null) '90th_percentile_gpu_frame_time',
|
||||
if (data['99th_percentile_gpu_frame_time'] != null) '99th_percentile_gpu_frame_time',
|
||||
if (data['worst_gpu_frame_time'] != null) 'worst_gpu_frame_time',
|
||||
// GPU Memory.
|
||||
if (data['average_gpu_memory_mb'] != null) 'average_gpu_memory_mb',
|
||||
if (data['90th_percentile_gpu_memory_mb'] != null) '90th_percentile_gpu_memory_mb',
|
||||
if (data['99th_percentile_gpu_memory_mb'] != null) '99th_percentile_gpu_memory_mb',
|
||||
if (data['worst_gpu_memory_mb'] != null) 'worst_gpu_memory_mb',
|
||||
]
|
||||
],
|
||||
);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'percentile_utils.dart';
|
||||
import 'timeline.dart';
|
||||
|
||||
/// Summarizes GPU/Device Memory allocations performed by Impeller.
|
||||
class GPUMemorySumarizer {
|
||||
/// Creates a RasterCacheSummarizer given the timeline events.
|
||||
GPUMemorySumarizer(List<TimelineEvent> gpuEvents) {
|
||||
for (final TimelineEvent event in gpuEvents) {
|
||||
final Object? value = event.arguments!['MemoryBudgetUsageMB'];
|
||||
if (value is String) {
|
||||
final double? parsedValue = double.tryParse(value);
|
||||
if (parsedValue != null) {
|
||||
_memoryMB.add(parsedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether or not this event is a GPU allocation event.
|
||||
static const Set<String> kMemoryEvents = <String>{'AllocatorVK'};
|
||||
|
||||
final List<double> _memoryMB = <double>[];
|
||||
|
||||
/// Computes the average GPU memory allocated.
|
||||
double computeAverageMemoryUsage() => _computeAverage(_memoryMB);
|
||||
|
||||
/// The [percentile]-th percentile GPU memory allocated.
|
||||
double computePercentileMemoryUsage(double percentile) {
|
||||
if (_memoryMB.isEmpty) {
|
||||
return 0;
|
||||
}
|
||||
return findPercentile(_memoryMB, percentile);
|
||||
}
|
||||
|
||||
/// Compute the worst allocation quantity recorded.
|
||||
double computeWorstMemoryUsage() => _computeWorst(_memoryMB);
|
||||
|
||||
static double _computeAverage(List<double> values) {
|
||||
if (values.isEmpty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double total = 0;
|
||||
for (final double data in values) {
|
||||
total += data;
|
||||
}
|
||||
return total / values.length;
|
||||
}
|
||||
|
||||
static double _computeWorst(List<double> values) {
|
||||
if (values.isEmpty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
values.sort();
|
||||
return values.last;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import 'common.dart';
|
|||
import 'frame_request_pending_latency_summarizer.dart';
|
||||
import 'gc_summarizer.dart';
|
||||
import 'gpu_sumarizer.dart';
|
||||
import 'memory_summarizer.dart';
|
||||
import 'percentile_utils.dart';
|
||||
import 'profiling_summarizer.dart';
|
||||
import 'raster_cache_summarizer.dart';
|
||||
|
@ -277,6 +278,7 @@ class TimelineSummary {
|
|||
final RefreshRateSummary refreshRateSummary = RefreshRateSummary(vsyncEvents: _extractNamedEvents(kUIThreadVsyncProcessEvent));
|
||||
final FrameRequestPendingLatencySummarizer frameRequestPendingLatencySummarizer = _frameRequestPendingLatencySummarizer();
|
||||
final GpuSumarizer gpuSummarizer = _gpuSumarizer();
|
||||
final GPUMemorySumarizer memorySumarizer = _memorySummarizer();
|
||||
|
||||
final Map<String, dynamic> timelineSummary = <String, dynamic>{
|
||||
'average_frame_build_time_millis': computeAverageFrameBuildTimeMillis(),
|
||||
|
@ -342,6 +344,10 @@ class TimelineSummary {
|
|||
'90th_percentile_gpu_frame_time': gpuSummarizer.computePercentileGPUTime(90.0),
|
||||
'99th_percentile_gpu_frame_time': gpuSummarizer.computePercentileGPUTime(99.0),
|
||||
'worst_gpu_frame_time': gpuSummarizer.computeWorstGPUTime(),
|
||||
'average_gpu_memory_mb': memorySumarizer.computeAverageMemoryUsage(),
|
||||
'90th_percentile_gpu_memory_mb': memorySumarizer.computePercentileMemoryUsage(90.0),
|
||||
'99th_percentile_gpu_memory_mb': memorySumarizer.computePercentileMemoryUsage(99.0),
|
||||
'worst_gpu_memory_mb': memorySumarizer.computeWorstMemoryUsage(),
|
||||
};
|
||||
|
||||
timelineSummary.addAll(profilingSummary);
|
||||
|
@ -501,4 +507,6 @@ class TimelineSummary {
|
|||
GCSummarizer _gcSummarizer() => GCSummarizer.fromEvents(_extractEventsWithNames(kGCRootEvents));
|
||||
|
||||
GpuSumarizer _gpuSumarizer() => GpuSumarizer(_extractEventsWithNames(GpuSumarizer.kGpuEvents));
|
||||
|
||||
GPUMemorySumarizer _memorySummarizer() => GPUMemorySumarizer(_extractEventsWithNames(GPUMemorySumarizer.kMemoryEvents));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:flutter_driver/src/driver/memory_summarizer.dart';
|
||||
|
||||
import '../common.dart';
|
||||
|
||||
TimelineEvent newGPUTraceEvent(double ms) => TimelineEvent(<String, dynamic>{
|
||||
'name': 'AllocatorVK',
|
||||
'ph': 'b',
|
||||
'args': <String, String>{
|
||||
'MemoryBudgetUsageMB': ms.toString()
|
||||
},
|
||||
});
|
||||
|
||||
void main() {
|
||||
test('Can process GPU memory usage times.', () {
|
||||
final GPUMemorySumarizer summarizer = GPUMemorySumarizer(<TimelineEvent>[
|
||||
newGPUTraceEvent(1024),
|
||||
newGPUTraceEvent(1024),
|
||||
newGPUTraceEvent(512),
|
||||
newGPUTraceEvent(2048),
|
||||
]);
|
||||
|
||||
expect(summarizer.computeAverageMemoryUsage(), closeTo(1152, 0.1));
|
||||
expect(summarizer.computePercentileMemoryUsage(50.0), closeTo(1024, 0.1));
|
||||
expect(summarizer.computeWorstMemoryUsage(), 2048);
|
||||
});
|
||||
}
|
|
@ -532,6 +532,10 @@ void main() {
|
|||
'90th_percentile_gpu_frame_time': 0,
|
||||
'99th_percentile_gpu_frame_time': 0,
|
||||
'worst_gpu_frame_time': 0,
|
||||
'average_gpu_memory_mb': 0,
|
||||
'90th_percentile_gpu_memory_mb': 0,
|
||||
'99th_percentile_gpu_memory_mb': 0,
|
||||
'worst_gpu_memory_mb': 0,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -667,6 +671,10 @@ void main() {
|
|||
'90th_percentile_gpu_frame_time': 0,
|
||||
'99th_percentile_gpu_frame_time': 0,
|
||||
'worst_gpu_frame_time': 0,
|
||||
'average_gpu_memory_mb': 0,
|
||||
'90th_percentile_gpu_memory_mb': 0,
|
||||
'99th_percentile_gpu_memory_mb': 0,
|
||||
'worst_gpu_memory_mb': 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue