blob: 4927998f32e40e7dbb36b1faebc486464674e86d [file] [log] [blame]
Josh Gao492bfbe2018-04-06 17:55:24 -07001#!/usr/bin/env python3
2#
3# Copyright (C) 2018 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import os
19import statistics
Josh Gaocf82c982019-02-28 15:36:48 -080020import subprocess
Fabien Sanglard05398b32023-11-14 11:25:59 -080021import sys
Josh Gaocf82c982019-02-28 15:36:48 -080022import tempfile
Josh Gao492bfbe2018-04-06 17:55:24 -070023import time
24
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070025transfer_size_mib = 100
26num_runs = 10
27
Fabien Sanglard05398b32023-11-14 11:25:59 -080028# Make sure environment is setup, otherwise "adb" module is not available.
29if os.getenv("ANDROID_BUILD_TOP") is None:
30 print("Run source/lunch before running " + sys.argv[0])
31 sys.exit()
32
Josh Gao492bfbe2018-04-06 17:55:24 -070033import adb
34
35def lock_min(device):
36 device.shell_nocheck(["""
37 for x in /sys/devices/system/cpu/cpu?/cpufreq; do
38 echo userspace > $x/scaling_governor
39 cat $x/scaling_min_freq > $x/scaling_setspeed
40 done
41 """])
42
43def lock_max(device):
44 device.shell_nocheck(["""
45 for x in /sys/devices/system/cpu/cpu?/cpufreq; do
46 echo userspace > $x/scaling_governor
47 cat $x/scaling_max_freq > $x/scaling_setspeed
48 done
49 """])
50
51def unlock(device):
52 device.shell_nocheck(["""
53 for x in /sys/devices/system/cpu/cpu?/cpufreq; do
54 echo ondemand > $x/scaling_governor
55 echo sched > $x/scaling_governor
56 echo schedutil > $x/scaling_governor
57 done
58 """])
59
60def harmonic_mean(xs):
61 return 1.0 / statistics.mean([1.0 / x for x in xs])
62
63def analyze(name, speeds):
64 median = statistics.median(speeds)
65 mean = harmonic_mean(speeds)
66 stddev = statistics.stdev(speeds)
67 msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s"
68 print(msg % (name, len(speeds), median, mean, stddev))
69
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070070def benchmark_sink(device=None, size_mb=transfer_size_mib):
Josh Gaocf82c982019-02-28 15:36:48 -080071 if device == None:
72 device = adb.get_device()
73
74 speeds = list()
75 cmd = device.adb_cmd + ["raw", "sink:%d" % (size_mb * 1024 * 1024)]
76
77 with tempfile.TemporaryFile() as tmpfile:
78 tmpfile.truncate(size_mb * 1024 * 1024)
79
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070080 for _ in range(0, num_runs):
Josh Gaocf82c982019-02-28 15:36:48 -080081 tmpfile.seek(0)
82 begin = time.time()
83 subprocess.check_call(cmd, stdin=tmpfile)
84 end = time.time()
85 speeds.append(size_mb / float(end - begin))
86
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070087 analyze("sink %dMiB (write RAM) " % size_mb, speeds)
Josh Gaocf82c982019-02-28 15:36:48 -080088
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070089def benchmark_source(device=None, size_mb=transfer_size_mib):
Josh Gaocf82c982019-02-28 15:36:48 -080090 if device == None:
91 device = adb.get_device()
92
93 speeds = list()
94 cmd = device.adb_cmd + ["raw", "source:%d" % (size_mb * 1024 * 1024)]
95
96 with open(os.devnull, 'w') as devnull:
Fabien Sanglard1261c8f2024-08-19 16:16:56 -070097 for _ in range(0, num_runs):
Josh Gaocf82c982019-02-28 15:36:48 -080098 begin = time.time()
99 subprocess.check_call(cmd, stdout=devnull)
100 end = time.time()
101 speeds.append(size_mb / float(end - begin))
102
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700103 analyze("source %dMiB (read RAM) " % size_mb, speeds)
Josh Gaocf82c982019-02-28 15:36:48 -0800104
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700105def benchmark_push(device=None, file_size_mb=transfer_size_mib):
Josh Gao492bfbe2018-04-06 17:55:24 -0700106 if device == None:
107 device = adb.get_device()
108
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700109 remote_path = "/data/local/tmp/adb_benchmark_push_tmp"
Josh Gao492bfbe2018-04-06 17:55:24 -0700110 local_path = "/tmp/adb_benchmark_temp"
111
112 with open(local_path, "wb") as f:
113 f.truncate(file_size_mb * 1024 * 1024)
114
115 speeds = list()
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700116 for _ in range(0, num_runs):
Josh Gao492bfbe2018-04-06 17:55:24 -0700117 begin = time.time()
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700118 parameters = ['-Z'] # Disable compression since our file is full of 0s
119 device.push(local=local_path, remote=remote_path, parameters=parameters)
Josh Gao492bfbe2018-04-06 17:55:24 -0700120 end = time.time()
121 speeds.append(file_size_mb / float(end - begin))
122
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700123 analyze("push %dMiB (write flash)" % file_size_mb, speeds)
Josh Gao492bfbe2018-04-06 17:55:24 -0700124
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700125def benchmark_pull(device=None, file_size_mb=transfer_size_mib):
Josh Gao492bfbe2018-04-06 17:55:24 -0700126 if device == None:
127 device = adb.get_device()
128
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700129 remote_path = "/data/local/tmp/adb_benchmark_pull_temp"
Josh Gao492bfbe2018-04-06 17:55:24 -0700130 local_path = "/tmp/adb_benchmark_temp"
131
132 device.shell(["dd", "if=/dev/zero", "of=" + remote_path, "bs=1m",
133 "count=" + str(file_size_mb)])
134 speeds = list()
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700135 for _ in range(0, num_runs):
Josh Gao492bfbe2018-04-06 17:55:24 -0700136 begin = time.time()
137 device.pull(remote=remote_path, local=local_path)
138 end = time.time()
139 speeds.append(file_size_mb / float(end - begin))
140
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700141 analyze("pull %dMiB (read flash) " % file_size_mb, speeds)
Josh Gao492bfbe2018-04-06 17:55:24 -0700142
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700143def benchmark_device_dd(device=None, file_size_mb=transfer_size_mib):
Josh Gao492bfbe2018-04-06 17:55:24 -0700144 if device == None:
145 device = adb.get_device()
146
Josh Gao492bfbe2018-04-06 17:55:24 -0700147 speeds = list()
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700148 for _ in range(0, num_runs):
Josh Gao492bfbe2018-04-06 17:55:24 -0700149 begin = time.time()
150 device.shell(["dd", "if=/dev/zero", "bs=1m",
151 "count=" + str(file_size_mb)])
152 end = time.time()
153 speeds.append(file_size_mb / float(end - begin))
154
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700155 analyze("dd %dMiB (write flash)" % file_size_mb, speeds)
Josh Gao492bfbe2018-04-06 17:55:24 -0700156
157def main():
Josh Gaob4077012018-10-12 18:01:27 -0700158 device = adb.get_device()
159 unlock(device)
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700160
Josh Gaocf82c982019-02-28 15:36:48 -0800161 benchmark_sink(device)
162 benchmark_source(device)
Josh Gaob4077012018-10-12 18:01:27 -0700163 benchmark_push(device)
164 benchmark_pull(device)
Fabien Sanglard1261c8f2024-08-19 16:16:56 -0700165 benchmark_device_dd(device)
Josh Gao492bfbe2018-04-06 17:55:24 -0700166
167if __name__ == "__main__":
168 main()