Skip to content

android : fix CPU variant fallback returning LITTLE cluster count#3770

Open
jinweihan-ai wants to merge 1 commit into
ggml-org:masterfrom
jinweihan-ai:fix/android-cpu-cluster-detection
Open

android : fix CPU variant fallback returning LITTLE cluster count#3770
jinweihan-ai wants to merge 1 commit into
ggml-org:masterfrom
jinweihan-ai:fix/android-cpu-cluster-detection

Conversation

@jinweihan-ai
Copy link
Copy Markdown
Contributor

Summary

The variant fallback in getHighPerfCpuCountByVariant() used countKeepingMin() while the primary frequency branch used countDroppingMin(). Both branches are meant to return the count of high-performance cores, so the asymmetry caused the variant branch to return the LITTLE cluster count instead of the big cluster.

On big.LITTLE SoCs, when /sys/devices/system/cpu/cpuN/cpufreq/cpuinfo_max_freq is unreadable (some restrictive Android distributions block it) and the code falls back to CPU variant, whisper ends up pinned to the LITTLE cores and inference throughput roughly halves.

Verified on Helio G85 by the reporter of #3602.

The asymmetry

Before this PR, in both WhisperCpuConfig.kt and CpuInfo.java:

// frequency branch — returns high-perf core count ✓
private fun getHighPerfCpuCountByFrequencies(): Int =
    getCpuValues(property = \"processor\") { getMaxCpuFrequency(it.toInt()) }
        .countDroppingMin()

// variant fallback — returns LITTLE core count ✗
private fun getHighPerfCpuCountByVariant(): Int =
    getCpuValues(property = \"CPU variant\") { it.substringAfter(\"0x\").toInt(radix = 16) }
        .countKeepingMin()   // ← counts cores WITH the min value (LITTLE cluster)

The two helpers are:

private fun List<Int>.countDroppingMin(): Int = count { it > min() }   // high-perf cores
private fun List<Int>.countKeepingMin(): Int = count { it == min() }   // LITTLE cores

Fix

Swap countKeepingMin()countDroppingMin() in the variant branch of both the Kotlin (whisper.android) and Java (whisper.android.java) examples. Matches the suggestion in #3602.

Test plan

  • ${\textsf{git diff}}$ is a 2-line change in 2 files
  • Manually re-read both files to confirm the frequency branch already uses countDroppingMin() — the fix restores symmetry rather than introducing a new behavior
  • Real-device verification was done by the issue reporter on Helio G85; I do not have a big.LITTLE Android device to retest

Fixes #3602

The variant fallback in getHighPerfCpuCountByVariant() used
countKeepingMin() while the primary frequency branch used
countDroppingMin(). Both branches are meant to return the count of
high-performance cores, so the asymmetry caused the variant branch to
return the LITTLE cluster count instead.

On big.LITTLE SoCs, when cpuinfo_max_freq is unreadable and the code
falls back to CPU variant (verified by the reporter on Helio G85 in
ggml-org#3602), whisper ends up running on the LITTLE
cores and inference throughput roughly halves.

Fix mirrors the suggestion in the issue: use countDroppingMin() in the
variant branch, matching the frequency branch. Both the Kotlin
(whisper.android) and Java (whisper.android.java) examples share the
same asymmetry and are fixed together.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android (Kotlin): getHighPerfCpuCountByVariant gives the number of cores in the slowest core-cluster

1 participant