MTK PerfService介绍

1、在MTK芯片上如何控制CPU的核数和频率-MTK PerfService

一句话:PerfService就是用来调整CPU/GPU资源的。对于老的API,可以更简单地讲就是调CPU核数和CPU频率的。

1.1PerfService简介

kernel中实现了两个driver,一个负责控制开关CPU的核数,叫做hot-plug驱动,另一个负责调整CPU的频率,叫做DVFS驱动。 
kernel
中的driver会根据系统的负载情况下,自动调整使用几个CPU和调整CPU频率。如果负载高了,提高频率,或者多开几个核,或者开大核。如果负载降下去了,就可以关大核,关核,降频。

虽然现在的自动调频和调核的策略已经定义了很多,也在不断地完善,但是有两个问题:一是总有覆盖不到的情况,或者干脆就是互相矛盾的需求导致策略冲突。二是自动调度都是后知后觉的,只有发现负载上来了或者降下去了,才来做负载调节,需要一定的时间。这样,要么是效率不够,要么是功耗无谓地消耗掉。

PerfService就是一个在用户空间来主动调节系统能力的服务。

1.2C/C++调用PerfService

步骤

  • 动态加载libperfservicenative.so
  • 注册用户场景PerfServiceNative_userReg/PerfServiceNative_userRegBigLittle/PerfServiceNative_userRegScn
  • 激活用户场景PerfServiceNative_userEnable
  • 执行用户场景
  • 反激活用户场景PerfServiceNative_userDisable
  • 退出进程之前反注册PerfServiceNative_userUnreg/PerfServiceNative_userUnregScn

1.2.1老API的步骤

API只能对CPU做调度,但是好处是可以直接指定开几个核,频率调到多少,还可以控制开大核还是小核。

  • PerfServiceNative_userReg可以指定几个核和多高的频率
  • PerfServiceNative_userRegBigLittle还可以用来指定调度大小核
  • PerfServiceNative_userEnable用来激活上面注册的场景,PerfServiceNative_userEnableTimeout可以指定激活的超时时间
  • PerfServiceNative_userDisable用来反激活
  • PerfServiceNative_userUnreg反注册

1.2.2新API的步骤

新的API也可以调节GPU,但是采用的方式要复杂一些,就不再像老API一样直接指定核和频率了,需要定义配置

  • PerfServiceNative_userRegScn:没有参数,直接注册就好
  • PerfServiceNative_userRegScnConfig:用这个函数去真正指定配置
  • PerfServiceNative_userEnable/PerfServiceNative_userEnableTimeout:跟老API没有区别
  • PerfServiceNative_userDisable:还是老的API
  • PerfServiceNative_userUnregScn:反注册

1.2.3老API开发指南

指定核和频率PerfServiceNative_userReg

定义一个需要scn_core个核,scn_freq频率运行的任务

原型:

int  PerfServiceNative_userReg(int scn_core, int scn_freq);

定义于:/mediatek/proprietary/hardware/perfservice/perfservicenative/PerfServiceNative.h

参数: 
* scn_core:
开多少个核 
* scn_freq:
频率调整到多少。如果只是希望多开几个核或者少开几个核,并不关注频率的话,可以置成0.

返回值: 
* -1:
失败 
* other:handler
,用于后续的操作

注册指定大核小核PerfServiceNative_userRegBigLittle

定义一个需要scn_core个核,scn_freq频率运行的任务

原型:

int  PerfServiceNative_userRegBigLittle(int scn_core_big, int scn_freq_big,int scn_core_little, int scn_freq_little);

定义于:/mediatek/proprietary/hardware/perfservice/perfservicenative/PerfServiceNative.h

参数: 
* scn_core_big:
开多少个核 
* scn_freq_big:
频率调整到多少 
* scn_core_little:
开多少个核 
* scn_freq_little:
频率调整到多少

返回值: 
* -1:
失败 
* other:handler

反注册

在退出进程之前需要进行反注册

原型:

void PerfServiceNative_userUnreg(int handle);

激活和反激活

注册了之后也不是一直用啊,用的时候再打开吧,使用PerfServiceNative_userEnable。如果一旦忧心有可能出exception之类的流程不能保证走到PerfServiceNative_userDisable的话,也可以加个超时,调用PerfServiceNative_userEnableTimeout.

原型:

void PerfServiceNative_userEnable(int handle);
void PerfServiceNative_userDisable(int handle);
void PerfServiceNative_userEnableTimeout(int handle, int timeout);
void PerfServiceNative_userEnableTimeoutMs(int handle, int timeout);

参数: 
* handle:
注册成功后返回的那个 
* timeout: PerfServiceNative_userEnableTimeout
是以秒为单位的超时时间,PerfServiceNative_userEnableTimeoutMs则以毫秒为单位。

1.2.4新API开发指南

获取系统能力

int  PerfServiceNative_userGetCapability(int cmd);

参数: 
* cmd:
请参见下面的枚举值:

enum {
    CMD_GET_CPU_FREQ_LEVEL_COUNT        = 0,
    CMD_GET_CPU_FREQ_LITTLE_LEVEL_COUNT = 1,
    CMD_GET_CPU_FREQ_BIG_LEVEL_COUNT    = 2,
    CMD_GET_GPU_FREQ_LEVEL_COUNT        = 3,
    CMD_GET_MEM_FREQ_LEVEL_COUNT        = 4,
};
  • CMD_GET_CPU_FREQ_LEVEL_COUNT:获取CPU频率级别
  • CMD_GET_CPU_FREQ_LITTLE_LEVEL_COUNT:获取小核CPU频率级别
  • CMD_GET_CPU_FREQ_BIG_LEVEL_COUNT:获取大核CPU频率级别
  • CMD_GET_GPU_FREQ_LEVEL_COUNT:获取GPU频率级别
  • CMD_GET_MEM_FREQ_LEVEL_COUNT:获取内存频率级别

注册

因为新的API还需要指定配置,所以注册获取handle就不需要参数了。

原型:

int  PerfServiceNative_userRegScn();

反注册

反注册PerfServiceNative_userRegScn注册的handle。注意,跟PerfServiceNative_userUnreg不一样啊。

void PerfServiceNative_userUnregScn(int handle);

配置

原型:

void PerfServiceNative_userRegScnConfig(int   handle, 
int   cmd, 
int   param_1, 
int   param_2, 
int   param_3, 
int   param_4);

参数: 
* handle:PerfServiceNative_userRegScn
注册的handle 
* cmd:
命令 
* param_1, param_2, param_3, param_4:
根据命令不同的参数

命令请参见下面的枚举:

enum {
    CMD_SET_CPU_CORE_MIN    =0,
    CMD_SET_CPU_CORE_MAX    =1,
    CMD_SET_CPU_CORE_BIG_LITTLE_MIN =2,
    CMD_SET_CPU_CORE_BIG_LITTLE_MAX = 3,
    CMD_SET_CPU_FREQ_MIN            = 4,
    CMD_SET_CPU_FREQ_MAX            = 5,
    CMD_SET_CPU_FREQ_BIG_LITTLE_MIN = 6,
    CMD_SET_CPU_FREQ_BIG_LITTLE_MAX = 7,
    CMD_SET_GPU_FREQ_MIN            = 8,
    CMD_SET_GPU_FREQ_MAX            = 9,
    CMD_SET_MEM_FREQ_MIN            = 10,
    CMD_SET_MEM_FREQ_MAX            = 11,
    CMD_SET_VCORE                   = 12,
    CMD_SET_SCREEN_OFF_STATE        = 13,
    CMD_SET_CPUFREQ_HISPEED_FREQ    = 14,
    CMD_SET_CPUFREQ_MIN_SAMPLE_TIME = 15,
    CMD_SET_CPUFREQ_ABOVE_HISPEED_DELAY =16,
};
  • CMD_SET_CPU_CORE_MIN:设置最少核数.参数1个 - param_1:核数
  • CMD_SET_CPU_CORE_MAX:设置最大核数.参数1个 - param_1:核数
  • CMD_SET_CPU_CORE_BIG_LITTLE_MIN:设置最少大小核数.参数2个 - param_1:大核数,param_2:小核数
  • CMD_SET_CPU_CORE_BIG_LITTLE_MAX:设置最大大小核数.参数2个 - param_1:大核数,param_2:小核数
  • CMD_SET_CPU_FREQ_MIN:设置最低频率.参数1个 - param_1:频率
  • CMD_SET_CPU_FREQ_MAX:设置最高频率.参数1个 - param_1:频率
  • CMD_SET_CPU_FREQ_BIG_LITTLE_MIN:设置最低大小核数.参数2个 - param_1:大核频率,param_2:小核频率
  • CMD_SET_CPU_FREQ_BIG_LITTLE_MAX:设置最高大小核数.参数2个 - param_1:大核频率,param_2:小核频率
  • CMD_SET_GPU_FREQ_MIN:设置GPU最低频率级别,参数1个 - param_1:频率级别
  • CMD_SET_GPU_FREQ_MAX:不支持
  • CMD_SET_MEM_FREQ_MIN:不支持
  • CMD_SET_MEM_FREQ_MAX:不支持
  • CMD_SET_VCORE:设置图形模式,参数1个:DRAM模式:0-默认模式,1-低功耗模式,2-还是默认模式,3-高性能模式
  • CMD_SET_SCREEN_OFF_STATE:设置关屏模式,一个参数,模式值。0-关屏无效,1-关屏有效,2-关屏暂停,打开恢复
  • CMD_SET_CPUFREQ_HISPEED_FREQ:设置高速频率,一个参数。
  • CMD_SET_CPUFREQ_MIN_SAMPLE_TIME:设置最小采样值,一个参数。
  • CMD_SET_CPUFREQ_ABOVE_HISPEED_DELAY:设置above speed hispeed,一个参数。

开关屏的参数,请使用下面的枚举值:

enum {
    SCREEN_OFF_DISABLE      = 0,
    SCREEN_OFF_ENABLE       = 1,
    SCREEN_OFF_WAIT_RESTORE = 2,
};

1.3Java调用PerfService

1.3.1步骤

  • import IPerfServiceWrapper和PerfServiceWrapper
  • 注册用户场景IPerfServiceWrapper.userReg
  • 激活用户场景IPerfServiceWrapper.userEnable
  • 执行用户场景
  • 反激活用户场景IPerfServiceWrapper.userDisable
  • 反注册用户场景IPerfServiceWrapper.userUnreg

IPerfServiceWrapper定义于 
/frameworks/base/core/
Java/com/mediatek/perfservice/IPerfServiceWrapper.java

1.3.2老API的步骤

API只能对CPU做调度,但是好处是可以直接指定开几个核,频率调到多少,还可以控制开大核还是小核。

  • IPerfServiceWrapper.userReg可以指定几个核和多高的频率
  • IPerfServiceWrapper.userRegBigLittle还可以用来指定调度大小核
  • IPerfServiceWrapper.userEnable用来激活上面注册的场景,IPerfServiceWrapper.userEnableTimeout可以指定激活的超时时间
  • IPerfServiceWrapper.userDisable用来反激活
  • IPerfServiceWrapper.userUnreg反注册

1.3.3新API的步骤

新的API也可以调节GPU,但是采用的方式要复杂一些,就不再像老API一样直接指定核和频率了,需要定义配置

  • IPerfServiceWrapper.userRegScn:没有参数,直接注册就好
  • IPerfServiceWrapper.userRegScnConfig:用这个函数去真正指定配置
  • IPerfServiceWrapper.userEnable/IPerfServiceWrapper.userEnableTimeout:跟老API没有区别
  • IPerfServiceWrapper.userDisable:还是老的API
  • IPerfServiceWrapper.userUnregScn:反注册

1.3.4老API开发指南

指定核和频率PerfServiceNative_userReg

定义一个需要scn_core个核,scn_freq频率运行的任务

原型:

publicintuserReg(int  scn_core, 
int  scn_freq);

参数: 
* scn_core:
开多少个核 
* scn_freq:
频率调整到多少。如果只是希望多开几个核或者少开几个核,并不关注频率的话,可以置成0.

返回值: 
* -1:
失败 
* other:handler
,用于后续的操作

注册指定大核小核PerfServiceNative_userRegBigLittle

定义一个需要scn_core个核,scn_freq频率运行的任务

原型:

publicintuserRegBigLittle(int  scn_core_big, 
int  scn_freq_big, 
int  scn_core_little, 
int  scn_freq_little);

参数: 
* scn_core_big:
开多少个核 
* scn_freq_big:
频率调整到多少 
* scn_core_little:
开多少个核 
* scn_freq_little:
频率调整到多少

返回值: 
* -1:
失败 
* other:handler

反注册

在退出进程之前需要进行反注册

原型:

publicvoiduserUnreg(int  handle);

激活和反激活

注册了之后也不是一直用啊,用的时候再打开吧,使用PerfServiceNative_userEnable。如果一旦忧心有可能出exception之类的流程不能保证走到PerfServiceNative_userDisable的话,也可以加个超时,调用PerfServiceNative_userEnableTimeout.

原型:

publicvoiduserEnable(int  handle);
publicvoiduserEnableTimeout(int  handle, int timeout);
publicvoiduserEnableTimeoutMs( int handle, int  timeout_ms);
publicvoiduserDisable (  int   handle);

参数: 
* handle:
注册成功后返回的那个 
* timeout: PerfServiceNative_userEnableTimeout
是以秒为单位的超时时间,PerfServiceNative_userEnableTimeoutMs则以毫秒为单位。

1.3.5新API开发指南

获取系统能力
publicintuserGetCapability ( int  cmd);

参数: 
* cmd:
请参见下面的常量值:

publicstaticfinalint CMD_GET_CPU_FREQ_LEVEL_COUNT        = 0 ;
publicstaticfinalint  CMD_GET_CPU_FREQ_LITTLE_LEVEL_COUNT = 1 ;
publicstaticfinalint  CMD_GET_CPU_FREQ_BIG_LEVEL_COUNT    = 2 ;
publicstaticfinalint  CMD_GET_GPU_FREQ_LEVEL_COUNT        = 3 ;
publicstaticfinalint   CMD_GET_MEM_FREQ_LEVEL_COUNT        = 4 ;
  • CMD_GET_CPU_FREQ_LEVEL_COUNT:获取CPU频率级别
  • CMD_GET_CPU_FREQ_LITTLE_LEVEL_COUNT:获取小核CPU频率级别
  • CMD_GET_CPU_FREQ_BIG_LEVEL_COUNT:获取大核CPU频率级别
  • CMD_GET_GPU_FREQ_LEVEL_COUNT:获取GPU频率级别
  • CMD_GET_MEM_FREQ_LEVEL_COUNT:获取内存频率级别
注册

因为新的API还需要指定配置,所以注册获取handle就不需要参数了。

原型:

publicintuserRegScn ();
反注册

反注册PerfServiceNative_userRegScn注册的handle。注意,跟PerfServiceNative_userUnreg不一样啊。

原型:

publicvoiduserUnregScn ( int  handle);
配置

原型:

publicvoiduserRegScnConfig ( int  handle, int  cmd, int  param_1, int  param_2, int  param_3, int  param_4);

参数: 
* handle:PerfServiceNative_userRegScn
注册的handle 
* cmd:
命令 
* param_1, param_2, param_3, param_4:
根据命令不同的参数

命令请参见下面的常量:

publicstaticfinalint CMD_SET_CPU_CORE_MIN            = 0;
publicstaticfinalint CMD_SET_CPU_CORE_MAX            = 1;
publicstaticfinalint CMD_SET_CPU_CORE_BIG_LITTLE_MIN = 2;
publicstaticfinalint CMD_SET_CPU_CORE_BIG_LITTLE_MAX =3;
publicstaticfinalint CMD_SET_CPU_FREQ_MIN            = 4;
publicstaticfinalint CMD_SET_CPU_FREQ_MAX            = 5;
publicstaticfinalint CMD_SET_CPU_FREQ_BIG_LITTLE_MIN = 6;
publicstaticfinalint  CMD_SET_CPU_FREQ_BIG_LITTLE_MAX = 7;
publicstaticfinalint CMD_SET_GPU_FREQ_MIN            = 8;
publicstaticfinalint CMD_SET_GPU_FREQ_MAX            = 9;
publicstaticfinalint CMD_SET_MEM_FREQ_MIN            = 10;
publicstaticfinalint CMD_SET_MEM_FREQ_MAX            = 11;
publicstaticfinalint CMD_SET_SCREEN_OFF_STATE        = 12;
publicstaticfinalint CMD_SET_CPUFREQ_HISPEED_FREQ    = 13;
publicstaticfinalint CMD_SET_CPUFREQ_MIN_SAMPLE_TIME = 14;
publicstaticfinalint CMD_SET_CPUFREQ_ABOVE_HISPEED_DELAY = 15;
publicstaticfinalint CMD_SET_VCORE                      = 16;
  • CMD_SET_CPU_CORE_MIN:设置最少核数.参数1个 - param_1:核数
  • CMD_SET_CPU_CORE_MAX:设置最大核数.参数1个 - param_1:核数
  • CMD_SET_CPU_CORE_BIG_LITTLE_MIN:设置最少大小核数.参数2个 - param_1:大核数,param_2:小核数
  • CMD_SET_CPU_CORE_BIG_LITTLE_MAX:设置最大大小核数.参数2个 - param_1:大核数,param_2:小核数
  • CMD_SET_CPU_FREQ_MIN:设置最低频率.参数1个 - param_1:频率
  • CMD_SET_CPU_FREQ_MAX:设置最高频率.参数1个 - param_1:频率
  • CMD_SET_CPU_FREQ_BIG_LITTLE_MIN:设置最低大小核数.参数2个 - param_1:大核频率,param_2:小核频率
  • CMD_SET_CPU_FREQ_BIG_LITTLE_MAX:设置最高大小核数.参数2个 - param_1:大核频率,param_2:小核频率
  • CMD_SET_GPU_FREQ_MIN:设置GPU最低频率级别,参数1个 - param_1:频率级别
  • CMD_SET_GPU_FREQ_MAX:不支持
  • CMD_SET_MEM_FREQ_MIN:不支持
  • CMD_SET_MEM_FREQ_MAX:不支持
  • CMD_SET_VCORE:设置图形模式,参数1个:DRAM模式:0-默认模式,1-低功耗模式,2-还是默认模式,3-高性能模式
  • CMD_SET_SCREEN_OFF_STATE:设置关屏模式,一个参数,模式值。0-关屏无效,1-关屏有效,2-关屏暂停,打开恢复
  • CMD_SET_CPUFREQ_HISPEED_FREQ:设置高速频率,一个参数。
  • CMD_SET_CPUFREQ_MIN_SAMPLE_TIME:设置最小采样值,一个参数。
  • CMD_SET_CPUFREQ_ABOVE_HISPEED_DELAY:设置above speed hispeed,一个参数。

1.3.6Java调用例

WebView中的应用例

例:

publicvoidloadData(String data, String mimeType, String encoding) {
checkThread();
if (TRACE) Log.d(LOGTAG, "loadData");
/// M:PerfBoost include @{
if (sFirstLoadData) {
int maxFreq = 0;
try {
   String freqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
    RandomAccessFile reader = newRandomAccessFile(freqFile, "r");
    String stringMaxFreq = reader.readLine();
    reader.close();
     maxFreq = Integer.parseInt(stringMaxFreq);
            } catch (IOException | NumberFormatException e) {
e.printStackTrace();
            }
if (maxFreq != 0) {
sPerfService = new PerfServiceWrapper(null);
if (sPerfService != null) {
int minCPU = 2;
if (maxFreq <1100000)
minCPU = 4;
sPerfHandle = sPerfService.userReg(minCPU, maxFreq);
if (sPerfHandle != -1) {
sPerfService.userEnableTimeoutMs(sPerfHandle, 500);
Handler handler = newHandler();
handler.postDelayed(new Runnable() {
@Override
publicvoidrun() {
sPerfService.userUnreg(sPerfHandle);
             }
             }, 600);
                   }
               }
           }
sFirstLoadData = false;
        }
/// @}
 
mProvider.loadData(data, mimeType, encoding);
    }
AmSWmS中的应用例

下面是/frameworks/base/services/core/java/com/Android/server/am/ActivityStack.java中定义的perfBoost的两个方法,一个是perfBoostResume,另一个是perfBoostPause. 
这个就是下节我们要介绍的SCN_APP_SWITCH场景。

privatevoidperfBoostResume() {
if (mPerfService == null) {
mPerfService = new PerfServiceWrapper(null);
        }
 
if (mPerfService != null) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "amPerfBoost", 0);
if (DEBUG_PERFSRV) {Slog.d(TAG, "boostEnableTimeoutMs(" +   IPerfServiceWrapper.SCN_APP_SWITCH + ") cross app");
            }
mPerfService.boostEnableTimeoutMs(IPerfServiceWrapper.SCN_APP_SWITCH, BOOST_ENABLE_TIMEOUT);
        } else {Slog.e(TAG, "PerfService is not ready!");
        }
    }
 
publicvoidperfBoostPause() {
if (mPerfService == null) {
mPerfService = new PerfServiceWrapper(null);
        }
 
if (mPerfService != null) {
if (DEBUG_PERFSRV) {Slog.d(TAG, "boostDisable(" +  IPerfServiceWrapper.SCN_APP_SWITCH + ") cross app");    }
mPerfService.boostDisable(IPerfServiceWrapper.SCN_APP_SWITCH);
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "amPerfBoost", 0);
        } else {
Slog.e(TAG, "perfBoostPause, PerfService is not ready!");
        }
    }

我们再看一个

if (!mIsPerfBoostEnable) {
if (mPerfService == null) {
mPerfService = new PerfServiceWrapper(null);
                }
mPerfService.boostEnable(IPerfServiceWrapper.SCN_APP_ROTATE);
mIsPerfBoostEnable = true;
            }

1.4MTK预定义的一些场景

MediaTek预定义了这么多API,当然它自己也会有自己的预定义场景,这些场景就不需要再定义了。

1.4.1 libperfservice.so中预定义的场景

场景

cpu核数

cpu频率

UI操作

SCN_APP_SWITCH

2

-

app启动、退出

SCN_APP_ROTATE

2

-

app rotate

SCN_APP_TOUCH

2

169000

touch

但是,这个值肯定不是在所有平台上都是最优的值啊,所以MTK也提供了客户定制化的机制。

1.4.2定制预定义场景

定义于/vendor/mediatek/proprietary/hardware/perfservice/mt[xxxx]/scn_tbl/perfservscntbl.txt中。

我们以MT6735为例,来看一看具体的内容,定义于/vendor/mediatek/proprietary/hardware/perfservice/mt6735/scn_tbl/perfservscntbl.txt中。

CMD_SET_CPU_CORE, SCN_APP_TOUCH, 3
CMD_SET_CPU_FREQ, SCN_APP_TOUCH, 819000
CMD_SET_CPU_CORE, SCN_SW_FRAME_UPDATE, 3
CMD_SET_CPU_FREQ, SCN_SW_FRAME_UPDATE, 819000
CMD_SET_CPU_CORE, SCN_APP_SWITCH, 4
CMD_SET_CPU_FREQ, SCN_APP_SWITCH, 1300000
CMD_SET_CPU_UP_THRESHOLD, SCN_SW_FRAME_UPDATE, 80
CMD_SET_CPU_DOWN_THRESHOLD, SCN_SW_FRAME_UPDATE, 65
CMD_SET_CPU_CORE, SCN_APP_LAUNCH, 4
CMD_SET_CPU_FREQ, SCN_APP_LAUNCH, 1300000

1.4.3白名单

定义于:/vendor/mediatek/proprietary/hardware/perfservice/mt[xxxx]/app_list/perfservapplist.txt

格式:包名核数

例:

com.imangi.templerun2 3

1.5MTK平台控制CPU核心和频率的程序(源代码)

之前的满血工具MTKboost,时间有限不打算研究下去了,正好也有人需要,就开源供有兴趣朋友试试
root控制的原理是利用了MTK平台的perfservice服务
一般6595之后的机器都会支持(具体看/system/lib/下有没有libperfservice.solibperfservicenative.so
6595
的话,Flyme5之后似乎是支持的,之前的旧版不行。
原理上参考https://yq.aliyun.com/articles/26696 这篇文章
个人只是做了一点微小的工作,抓log试了几个针对6797的参数
最近时间有限不打算研究下去了,正好也有人需要,就开源供有兴趣朋友试试
源码地址: http://pan.baidu.com/s/1hs0MAtm
其中Native文件夹是C写的原生代码部分。

说明:
*
注意,频率单位均为kHz
Native
界面的3个函数:
resetCPU();
取消所有的profile设置
setCPU
intbigNum, int bigFreq, int littleNum, int littleFreq);
旧版API:设置CPU大小核上线数量和频率
对于三集群的MT6797,只能设置高频A53 cluster和低频A53cluster,无法控制A72
bigNum:
大核心上线数量
bigFreq
:大核心频率
littleNum
:小核心上线数量
littleFreq
:小核心频率
对于MT6795这类,8个核心全部为小核心,则需要设置littleNum=8才能8核全开
setCluster(intcmd, int p1, int p2, int p3, int p4);
新版API:
cmd
为命令,p1p2,p3, p4为参数
cmd:2
设置最少大小核数,对于6797为高配A53和低频A53
参数2 - param_1:大核数,param_2:小核数
例如: setCluster(2, bigNum, littleNum,0,0);


cmd:3
设置最多大小核数,对于6797为高配A53和低频A53
参数2 - param_1:大核数,param_2:小核数
例如: setCluster(3, bigNum, littleNum,0,0);


cmd:8
设置GPU最低频率级别
参数1 - param_1:频率级别,级别越大,频率越高
例如: setCluster(8, gpu, 0,0,0);


由于上述文章和目前可供下载到的代码不是很新,并不支持MT6797三丛集
下面几个参数是文章中没有提供的,个人通过在6797平台上抓log试出来的
cmd:17
设置特定cluster的最小频率
参数2 - param_1cluster序号,param_2:频率
对于MT6797
低频A53 cluster 0
高频A53 cluster 1
A72
cluster 2
例如:

setCluster(17, 0, litteSFreq,0,0);
setCluster(17, 1, litteFreq,0,0);
setCluster(17, 2, bigFreq,0,0);


cmd:18
设置特定cluster的最大频率

参数2 - param_1cluster序号,param_2:频率
对于MT6797
低频A53 cluster 0
高频A53 cluster 1
A72
cluster 2


例如:
setCluster(17, 0, litteSFreq,0,0);
setCluster(17, 1, litteFreq,0,0);
setCluster(17, 2, bigFreq,0,0);


cmd:23
设置整体系统性能
MT6797
利用此命令去开启A72
参数1 - param_1:系统性能级别,貌似是301000的整数
例如: 
setCluster(23, 800, 0, 0, 0); //
开启8A53+1A72,满频
setCluster(23, 1000, 0, 0, 0); //
开启8A53+2A72,满频(安兔兔模式)
====

目前尚无发现直接对A72 cluster的核心数进行设置的命令
因此先采用cmd 23开启需要数量的A72,再对低频和高频A53的核心数进行限制
最后在对3cluster的频率进行限制
例如:
//
开启1A72
if(bigN==1){
//
强开8A53+1A72
setCluster(23, 800,0,0,0);
//
设置低频高频A53最小核心数
setCluster(2, littleN,littleSN,0,0);
//
设置低频高频A53最多核心数
setCluster(3, littleN,littleSN,0,0);
//18:
设置3cluster的最大频率
setCluster(18, 0,litteSF* 1000,0,0);
setCluster(18, 1,litteF* 1000,0,0);
setCluster(18, 2,bigF* 1000,0,0);
//17:
设置3cluster的最小频率
setCluster(17, 0,litteSF* 1000,0,0);
setCluster(17, 1,litteF* 1000,0,0);
setCluster(17, 2,bigF* 1000,0,0);
}
if(bigN ==2){
//
强开8A53+2A72,安兔兔模式
setCluster(23, 1000,0,0,0);
//
设置低频高频A53最小核心数
setCluster(2, littleN,littleSN,0,0);
//
设置低频高频A53最多核心数
setCluster(3, littleN,littleSN,0,0);
//18:
设置3cluster的最大频率
setCluster(18, 0,litteSF* 1000,0,0);
setCluster(18, 1,litteF* 1000,0,0);
setCluster(18, 2,bigF* 1000,0,0);
//17:
设置3cluster的最小频率
setCluster(17, 0,litteSF* 1000,0,0);
setCluster(17, 1,litteF* 1000,0,0);
setCluster(17, 2,bigF* 1000,0,0);
}
====================================
目前的问题:
0.
关闭屏幕会进入低功耗模式,清除原有的设置,这是系统限制。
1. MTK
或者厂家预先定义了部分场景,比如微博强制不开A72
在进入这些app后,perfservicestatus会被该app的预定义场景覆盖
比如好好的满血状态,进微博A72就下线了,回桌面又会上线。
2.
经过测试,cmd:23设置整体系统性能中的参数=1000(安兔兔模式)具有最高优先级
因此满血状态可以有效保持。
但在MT6797上,通过新API设置成各个cluster的频率和上线数量后,在MTKboost APP内没有问题,但返回桌面时系统似乎会通过perfservice重新设置A53/A72的数量和频率,导致设置在MTKboost APP外变的无效。(优先级不如安兔兔模式来的高)

 

 

 

 

2.MTK平台CPU/GPU动态调频的实现之PerfService的源码分析

1. 
}  


再看PerfServiceImpl类的实现:

[java] view plain copy

1.  public class PerfServiceImpl extends IPerfService.Stub {  

2.    

3.      private static final String TAG = "PerfService";  

4.    

5.      private IPerfServiceManager perfServiceMgr;  

6.      final   Context mContext;  

7.    

8.      // 接收锁屏/开屏的广播  

9.      class PerfServiceBroadcastReceiver extends android.content.BroadcastReceiver {  

10.         @Override  

11.         public void onReceive(Context context, Intent intent) {  

12.             final String action = intent.getAction();  

13.             if (Intent.ACTION_SCREEN_OFF.equals(action)) {  

14.                 log("Intent.ACTION_SCREEN_OFF");  

15.                 perfServiceMgr.userDisableAll();  

16.                 return;  

17.             }  

18.             else if (Intent.ACTION_SCREEN_ON.equals(action)) {  

19.                 log("Intent.ACTION_SCREEN_ON");  

20.                 perfServiceMgr.userRestoreAll();  

21.                 return;  

22.             }  

23.             else {  

24.                 log("Unexpected intent " + intent);  

25.             }  

26.         }  

27.     }  

28.   

29.     public PerfServiceImpl(Context context, IPerfServiceManager pm) {  

30.         perfServiceMgr = pm;  

31.         mContext = context;  

32.   

33.         final IntentFilter broadcastFilter = new IntentFilter();  

34.         broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF);  

35.         broadcastFilter.addAction(Intent.ACTION_SCREEN_ON);  

36.         mContext.registerReceiver(new PerfServiceBroadcastReceiver(), broadcastFilter);  

37.   

38.     }  

39.   

40.     // aidl中声明的其他方法  

41.     . . .  

42.   

43.     public void notifyAppState(java.lang.String packName, java.lang.String className,  

44.                                int state, int pid) {  

45.         //log("notifyAppState");  

46.         // 调用PerfServiceManager中的方法,最后调用的是native方法  

47.         perfServiceMgr.notifyAppState(packName, className, state, pid);  

48.     }  

49.   

50.     . . .  

51.   

52.     private void log(String info) {  

53.         Log.d("@M_" + TAG, "[PerfService] " + info + " ");  

54.     }  

55.   

56.     private void loge(String info) {  

57.         Log.e("@M_" + TAG, "[PerfService] ERR: " + info + " ");  

58.     }  

59. }  


另外:

vendor\mediatek\proprietary\hardware\perfservice\mt**\app_list目录下的perfservapplist.txt文件中可以自定义应用白名单,默认值为:

CMD_SET_CPU_CORE_MINcom.imangi.templerun2 3

意思是用户使用神庙逃亡应用时,CPU最少核心数为3

 

vendor\mediatek\proprietary\hardware\perfservice\mt**\scn_tbl目录下的perfservscntbl.txt文件中可以自定义场景,默认场景有:

CMD_SET_CPU_CORE_MIN,SCN_APP_TOUCH, 3
CMD_SET_CPU_FREQ_MIN, SCN_APP_TOUCH, 1014000
CMD_SET_CPU_CORE_MIN, SCN_SW_FRAME_UPDATE, 3
CMD_SET_CPU_FREQ_MIN, SCN_SW_FRAME_UPDATE, 1014000
CMD_SET_CPU_UP_THRESHOLD, SCN_SW_FRAME_UPDATE, 80
CMD_SET_CPU_DOWN_THRESHOLD, SCN_SW_FRAME_UPDATE, 65
CMD_SET_CPU_FREQ_BIG_LITTLE_MIN, SCN_APP_SWITCH, 1950000, 1144000
CMD_SET_CPU_CORE_BIG_LITTLE_MIN, SCN_APP_SWITCH, 4, 0
CMD_SET_VCORE, SCN_APP_SWITCH, 3
CMD_SET_CPU_FREQ_BIG_LITTLE_MIN, SCN_APP_ROTATE, 1950000, 1144000
CMD_SET_VCORE, SCN_APP_ROTATE, 3
CMD_SET_VCORE, SCN_GAMING, 1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值