1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
#
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#################################################################
###
### DO NOT MODIFY THIS FILE
### This is a copy of androidx's benchmark/lockClocks.sh
### Make changes there instead then copy here!
###
#################################################################
# This script can be used to lock device clocks to stable levels for comparing
# different versions of software. Since the clock levels are not necessarily
# indicative of real world behavior, this should **never** be used to compare
# performance between different device models.
# Fun notes for maintaining this file:
# `expr` can deal with ints > INT32_MAX, but if compares cannot. This is why we use MHz.
# `expr` can sometimes evaluate right-to-left. This is why we use parens.
# Everything below the initial host-check isn't bash - Android uses mksh
# mksh allows `\n` in an echo, bash doesn't
# can't use `awk`
CPU_TARGET_FREQ_PERCENT=50
GPU_TARGET_FREQ_PERCENT=50
if [ "`command -v getprop`" == "" ]; then
if [ -n "`command -v adb`" ]; then
echo ""
echo "Pushing $0 and running it on device..."
dest=/data/local/tmp/`basename $0`
adb push $0 ${dest}
adb shell ${dest}
adb shell rm ${dest}
exit
else
echo "Could not find adb. Options are:"
echo " 1. Ensure adb is on your \$PATH"
echo " 2. Use './gradlew lockClocks'"
echo " 3. Manually adb push this script to your device, and run it there"
exit -1
fi
fi
# require root
if [ "`id -u`" -ne "0" ]; then
echo "Not running as root, cannot lock clocks, aborting"
exit -1
fi
DEVICE=`getprop ro.product.device`
MODEL=`getprop ro.product.model`
# Find CPU max frequency, and lock big cores to an available frequency
# that's >= $CPU_TARGET_FREQ_PERCENT% of max. Disable other cores.
function_lock_cpu() {
CPU_BASE=/sys/devices/system/cpu
GOV=cpufreq/scaling_governor
# Find max CPU freq, and associated list of available freqs
cpuMaxFreq=0
cpuAvailFreqCmpr=0
cpuAvailFreq=0
enableIndices=''
disableIndices=''
cpu=0
while [ -f ${CPU_BASE}/cpu${cpu}/online ]; do
# enable core, so we can find its frequencies
echo 1 > ${CPU_BASE}/cpu${cpu}/online
maxFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/cpuinfo_max_freq`
availFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/scaling_available_frequencies`
availFreqCmpr=${availFreq// /-}
if [ ${maxFreq} -gt ${cpuMaxFreq} ]; then
# new highest max freq, look for cpus with same max freq and same avail freq list
cpuMaxFreq=${maxFreq}
cpuAvailFreq=${availFreq}
cpuAvailFreqCmpr=${availFreqCmpr}
if [ -z ${disableIndices} ]; then
disableIndices="$enableIndices"
else
disableIndices="$disableIndices $enableIndices"
fi
enableIndices=${cpu}
elif [ ${maxFreq} == ${cpuMaxFreq} ] && [ ${availFreqCmpr} == ${cpuAvailFreqCmpr} ]; then
enableIndices="$enableIndices $cpu"
else
disableIndices="$disableIndices $cpu"
fi
cpu=$(($cpu + 1))
done
# Chose a frequency to lock to that's >= $CPU_TARGET_FREQ_PERCENT% of max
# (below, 100M = 1K for KHz->MHz * 100 for %)
TARGET_FREQ_MHZ=`expr \( ${cpuMaxFreq} \* ${CPU_TARGET_FREQ_PERCENT} \) \/ 100000`
chosenFreq=0
for freq in ${cpuAvailFreq}; do
freqMhz=`expr ${freq} \/ 1000`
if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ]; then
chosenFreq=${freq}
break
fi
done
# enable 'big' CPUs
for cpu in ${enableIndices}; do
freq=${CPU_BASE}/cpu$cpu/cpufreq
echo 1 > ${CPU_BASE}/cpu${cpu}/online
echo userspace > ${CPU_BASE}/cpu${cpu}/${GOV}
echo ${chosenFreq} > ${freq}/scaling_max_freq
echo ${chosenFreq} > ${freq}/scaling_min_freq
echo ${chosenFreq} > ${freq}/scaling_setspeed
# validate setting the freq worked
obsCur=`cat ${freq}/scaling_cur_freq`
obsMin=`cat ${freq}/scaling_min_freq`
obsMax=`cat ${freq}/scaling_max_freq`
if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then
echo "Failed to set CPU$cpu to $chosenFreq Hz! Aborting..."
echo "scaling_cur_freq = $obsCur"
echo "scaling_min_freq = $obsMin"
echo "scaling_max_freq = $obsMax"
exit -1
fi
done
# disable other CPUs (Note: important to enable big cores first!)
for cpu in ${disableIndices}; do
echo 0 > ${CPU_BASE}/cpu${cpu}/online
done
echo "\nLocked CPUs ${enableIndices// /,} to $chosenFreq / $maxFreq KHz"
echo "Disabled CPUs ${disableIndices// /,}"
}
# If we have a Qualcomm GPU, find its max frequency, and lock to
# an available frequency that's >= GPU_TARGET_FREQ_PERCENT% of max.
function_lock_gpu_kgsl() {
if [ ! -d /sys/class/kgsl/kgsl-3d0/ ]; then
# not kgsl, abort
echo "\nCurrently don't support locking GPU clocks of $MODEL ($DEVICE)"
return -1
fi
if [ ${DEVICE} == "walleye" ] || [ ${DEVICE} == "taimen" ]; then
# Workaround crash
echo "\nUnable to lock GPU clocks of $MODEL ($DEVICE)"
return -1
fi
GPU_BASE=/sys/class/kgsl/kgsl-3d0
gpuMaxFreq=0
gpuAvailFreq=`cat $GPU_BASE/devfreq/available_frequencies`
for freq in ${gpuAvailFreq}; do
if [ ${freq} -gt ${gpuMaxFreq} ]; then
gpuMaxFreq=${freq}
fi
done
# (below, 100M = 1M for MHz * 100 for %)
TARGET_FREQ_MHZ=`expr \( ${gpuMaxFreq} \* ${GPU_TARGET_FREQ_PERCENT} \) \/ 100000000`
chosenFreq=${gpuMaxFreq}
index=0
chosenIndex=0
for freq in ${gpuAvailFreq}; do
freqMhz=`expr ${freq} \/ 1000000`
if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ] && [ ${chosenFreq} -ge ${freq} ]; then
# note avail freq are generally in reverse order, so we don't break out of this loop
chosenFreq=${freq}
chosenIndex=${index}
fi
index=$(($index + 1))
done
lastIndex=$(($index - 1))
firstFreq=`echo $gpuAvailFreq | cut -d" " -f1`
if [ ${gpuMaxFreq} != ${firstFreq} ]; then
# pwrlevel is index of desired freq among available frequencies, from highest to lowest.
# If gpuAvailFreq appears to be in-order, reverse the index
chosenIndex=$(($lastIndex - $chosenIndex))
fi
echo 0 > ${GPU_BASE}/bus_split
echo 1 > ${GPU_BASE}/force_clk_on
echo 10000 > ${GPU_BASE}/idle_timer
echo performance > ${GPU_BASE}/devfreq/governor
# NOTE: we store in min/max twice, because we don't know if we're increasing
# or decreasing, and it's invalid to try and set min > max, or max < min
echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq
echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq
echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq
echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq
echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel
echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel
echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel
echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel
obsCur=`cat ${GPU_BASE}/devfreq/cur_freq`
obsMin=`cat ${GPU_BASE}/devfreq/min_freq`
obsMax=`cat ${GPU_BASE}/devfreq/max_freq`
if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then
echo "Failed to set GPU to $chosenFreq Hz! Aborting..."
echo "cur_freq = $obsCur"
echo "min_freq = $obsMin"
echo "max_freq = $obsMax"
echo "index = $chosenIndex"
exit -1
fi
echo "\nLocked GPU to $chosenFreq / $gpuMaxFreq Hz"
}
# kill processes that manage thermals / scaling
stop thermal-engine
stop perfd
stop vendor.thermal-engine
stop vendor.perfd
function_lock_cpu
function_lock_gpu_kgsl
# Memory bus - hardcoded per-device for now
if [ ${DEVICE} == "marlin" ] || [ ${DEVICE} == "sailfish" ]; then
echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/max_freq
else
echo "\nUnable to lock memory bus of $MODEL ($DEVICE)."
fi
echo "\n$DEVICE clocks have been locked - to reset, reboot the device\n"
|