1
+ package com.whispercppdemo.whisper
2
+
3
+ import android.util.Log
4
+ import java.io.BufferedReader
5
+ import java.io.FileReader
6
+
7
+ object WhisperCpuConfig {
8
+ val preferredThreadCount: Int
9
+ // Always use at least 2 threads:
10
+ get() = CpuInfo .getHighPerfCpuCount().coerceAtLeast(2 )
11
+ }
12
+
13
+ private class CpuInfo (private val lines : List <String >) {
14
+ private fun getHighPerfCpuCount (): Int = try {
15
+ getHighPerfCpuCountByFrequencies()
16
+ } catch (e: Exception ) {
17
+ Log .d(LOG_TAG , " Couldn't read CPU frequencies" , e)
18
+ getHighPerfCpuCountByVariant()
19
+ }
20
+
21
+ private fun getHighPerfCpuCountByFrequencies (): Int =
22
+ getCpuValues(property = " processor" ) { getMaxCpuFrequency(it.toInt()) }
23
+ .also { Log .d(LOG_TAG , " Binned cpu frequencies (frequency, count): ${it.binnedValues()} " ) }
24
+ .countDroppingMin()
25
+
26
+ private fun getHighPerfCpuCountByVariant (): Int =
27
+ getCpuValues(property = " CPU variant" ) { it.substringAfter(" 0x" ).toInt(radix = 16 ) }
28
+ .also { Log .d(LOG_TAG , " Binned cpu variants (variant, count): ${it.binnedValues()} " ) }
29
+ .countKeepingMin()
30
+
31
+ private fun List<Int>.binnedValues () = groupingBy { it }.eachCount()
32
+
33
+ private fun getCpuValues (property : String , mapper : (String ) -> Int ) = lines
34
+ .asSequence()
35
+ .filter { it.startsWith(property) }
36
+ .map { mapper(it.substringAfter(' :' ).trim()) }
37
+ .sorted()
38
+ .toList()
39
+
40
+
41
+ private fun List<Int>.countDroppingMin (): Int {
42
+ val min = min()
43
+ return count { it > min }
44
+ }
45
+
46
+ private fun List<Int>.countKeepingMin (): Int {
47
+ val min = min()
48
+ return count { it == min }
49
+ }
50
+
51
+ companion object {
52
+ private const val LOG_TAG = " WhisperCpuConfig"
53
+
54
+ fun getHighPerfCpuCount (): Int = try {
55
+ readCpuInfo().getHighPerfCpuCount()
56
+ } catch (e: Exception ) {
57
+ Log .d(LOG_TAG , " Couldn't read CPU info" , e)
58
+ // Our best guess -- just return the # of CPUs minus 4.
59
+ (Runtime .getRuntime().availableProcessors() - 4 ).coerceAtLeast(0 )
60
+ }
61
+
62
+ private fun readCpuInfo () = CpuInfo (
63
+ BufferedReader (FileReader (" /proc/cpuinfo" ))
64
+ .useLines { it.toList() }
65
+ )
66
+
67
+ private fun getMaxCpuFrequency (cpuIndex : Int ): Int {
68
+ val path = " /sys/devices/system/cpu/cpu${cpuIndex} /cpufreq/cpuinfo_max_freq"
69
+ val maxFreq = BufferedReader (FileReader (path)).use { it.readLine() }
70
+ return maxFreq.toInt()
71
+ }
72
+ }
73
+ }
0 commit comments