当前位置: 首页 > news >正文

【Android】强制使用 CPU 大核或超大核

摘要

  • 说明:通过 JNI 在应用层读取 /sys/devices/system/cpu 下各核的 cpuinfo_max_freq,选出频率最高的核心集合,随机挑选一个并尝试把主线程绑定到该核,以期望获得更稳定或更高的主线程性能。

  • 目的:在需要主线程更稳定的短时间高负载场景(如关键 UI 动画或延迟敏感计算)尝试降低抖动。

实现要点

  • native 侧实现三个 JNI 方法:getMaxFreqCoresbindThreadToCoregetCurrentCpu;应用层调用这些方法决定是否绑定主线程。

  • getMaxFreqCores 通过读取每个 cpuN/cpufreq/cpuinfo_max_freq 找出最大频率并返回所有匹配核心索引。

  • bindThreadToCore 用 sched_setaffinity 将当前线程绑定到指定 CPU。

  • getCurrentCpu 用 sched_getcpu 返回当前线程运行的 CPU 编号,用于验证绑定是否生效。

示例代码

JNI:

#include <jni.h>
#include <string>
#include <unistd.h>extern "C"
JNIEXPORT jintArray JNICALL
Java_XXX_getMaxFreqCores(JNIEnv *env, jobject  /* this */) {char path[128];FILE *fp;int maxFreq = -1;// 获取CPU核心数int cpuCount = sysconf(_SC_NPROCESSORS_ONLN);int cores[cpuCount];int coreCount = 0;// 第一次遍历,找最大频率for (int i = 0; i < cpuCount; i++) {snprintf(path, sizeof(path),"/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);fp = fopen(path, "r");if (fp) {int freq = 0;if (fscanf(fp, "%d", &freq) == 1) {if (freq > maxFreq) {maxFreq = freq;}}fclose(fp);} else {break; // 核心不存在}}// 第二次遍历,把所有等于 maxFreq 的核心加入数组for (int i = 0; i < cpuCount; i++) {snprintf(path, sizeof(path),"/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);fp = fopen(path, "r");if (fp) {int freq = 0;if (fscanf(fp, "%d", &freq) == 1) {if (freq == maxFreq) {cores[coreCount++] = i;}}fclose(fp);} else {break;}}// 返回期望的结果jintArray result = env->NewIntArray(coreCount);if (result == nullptr) return nullptr;env->SetIntArrayRegion(result, 0, coreCount, cores);return result;
}extern "C"
JNIEXPORT jint JNICALL
Java_XXX_bindThreadToCore(JNIEnv *env, jobject /* this */, jint core) {cpu_set_t set;CPU_ZERO(&set);CPU_SET(core, &set);pid_t tid = gettid();int result = sched_setaffinity(tid, sizeof(set), &set);return result;  // 0 = 成功, -1 = 失败
}extern "C"
JNIEXPORT jint JNICALL
Java_XXX_getCurrentCpu(JNIEnv *env, jobject /* this */) {return sched_getcpu();
}

应用层调用:

class MainActivity : AppCompatActivity() {companion object {init {System.loadLibrary("jni")}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val maxFreqCores = getMaxFreqCores()maxFreqCores.forEach { core ->Log.d("Tyhoo", "最高频率核心: cpu$core")}val result = isCurrentInMaxFreqCore(maxFreqCores)if (!result) {// 随机选择一个最高频率核心val randomMaxFreqCore = maxFreqCores.random()Log.d("Tyhoo", "将主线程绑定到最高频率核心 cpu$randomMaxFreqCore")val ret = bindThreadToCore(randomMaxFreqCore)if (ret == 0) {Log.d("Tyhoo", "主线程已绑定到 cpu$randomMaxFreqCore")isCurrentInMaxFreqCore(maxFreqCores)} else {Log.d("Tyhoo", "绑定失败,错误码: $ret")}}}private fun isCurrentInMaxFreqCore(cores: IntArray): Boolean {val currentCpu = getCurrentCpu()if (cores.contains(currentCpu)) {Log.d("Tyhoo", "主线程正在运行在最高频率核心 cpu$currentCpu")return true} else {Log.d("Tyhoo", "主线程在 cpu$currentCpu, 不是最高频率核心 ${cores.joinToString(", ") { "cpu$it" }}")return false}}external fun getMaxFreqCores(): IntArrayexternal fun bindThreadToCore(core: Int): Intexternal fun getCurrentCpu(): Int
}

打印日志:

com.tyhoo.example.jni                  D  最高频率核心: cpu0
com.tyhoo.example.jni                  D  最高频率核心: cpu1
com.tyhoo.example.jni                  D  最高频率核心: cpu2
com.tyhoo.example.jni                  D  最高频率核心: cpu3
com.tyhoo.example.jni                  D  主线程在 cpu5, 不是最高频率核心 cpu0, cpu1, cpu2, cpu3
com.tyhoo.example.jni                  D  将主线程绑定到最高频率核心 cpu1
com.tyhoo.example.jni                  D  主线程已绑定到 cpu1
com.tyhoo.example.jni                  D  主线程正在运行在最高频率核心 cpu1

结论

该方案实现简单、不改动架构,适合做短期实验和定位性能抖动。但生产环境使用前必须做好兼容性、稳健性与性能回归测试,避免因绑定主线程带来意外副作用。

http://www.dtcms.com/a/427133.html

相关文章:

  • 【算法竞赛学习笔记】基础概念篇:算法复杂度
  • SLA操作系统双因素认证实现Windows远程桌面OTP双因子安全登录—从零搭建企业级RDP安全加固体系
  • 现在主流的网站开发语言360房产网郑州官网
  • 石家庄哪个公司做网站好做外贸c2c网站有哪些
  • 伪路径约束
  • 新天力:以全链协同能力构筑食品容器行业领军优势
  • Markdown转换为Word:Pandoc模板使用指南
  • Cloudflare 开源 VibeSDK:开启“氛围编程”新时代的全栈 AI 应用生成平台
  • 汕头网站建设sagevis企业网站建设有什么好处
  • C语言趣味小游戏----猜数字小游戏
  • 多表关联对集中式数据库和分布式数据库系统冲击
  • Suifest 2025 活动速递
  • 交叉熵损失函数和负对数似然损失函数 KL散度
  • 坪地网站建设教程网站seo优化方法
  • 网站数据库多大合适成都小型软件开发公司
  • Gibbs采样:全面解析马尔可夫链蒙特卡洛的核心算法
  • 【开题答辩全过程】以 python的音乐网站为例,包含答辩的问题和答案
  • 二项式定理——力扣2221.数组的三角和
  • 【数据结构】快速排序与归并排序的实现
  • LeetCode算法日记 - Day 57: 括号生成、组合
  • FinalShell 服务器远程连接工具
  • 分享:一键自动化巡检服务器
  • 广州建站快车加盟网网站建设策划书
  • 12306网站架构站长之家seo综合
  • 学习:uniapp全栈微信小程序vue3后台-额外/精彩报错篇
  • 【云服务器相关】云服务器与P2P
  • vscode终端输出中文乱码一种解决方法
  • 脑机接口(BCI):从信号到交互的工程实践
  • 更改mysql密码
  • 同步与互斥