簡(jiǎn)介
性能調(diào)優(yōu)組件包含系統(tǒng)和應(yīng)用調(diào)優(yōu)框架,旨在為開發(fā)者提供一套性能調(diào)優(yōu)平臺(tái),可以用來(lái)分析內(nèi)存、性能等問題。
該組件整體分為PC端和設(shè)備端兩部分,PC端最終作為deveco studio的插件進(jìn)行發(fā)布,內(nèi)部主要包括分為UI繪制、設(shè)備管理、進(jìn)程管理、插件管理、數(shù)據(jù)導(dǎo)入、數(shù)據(jù)存儲(chǔ)、 數(shù)據(jù)分析、Session管理、配置管理等模塊;設(shè)備端主要包括命令行工具、服務(wù)進(jìn)程、插件集合、應(yīng)用程序組件等模塊。設(shè)備端提供了插件擴(kuò)展能力,對(duì)外提供了插件接口,基于該擴(kuò)展能力可以按需定義自己的能力,并集成到框架中來(lái),目前基于插件能力已經(jīng)完成了實(shí)時(shí)內(nèi)存插件,trace插件。下文會(huì)重點(diǎn)對(duì)設(shè)備端提供的插件能力進(jìn)行介紹。
架構(gòu)圖
說明
下面針對(duì)設(shè)備端對(duì)外提供的插件擴(kuò)展能力進(jìn)行接口和使用說明。
接口說明
下面是設(shè)備端插件模塊對(duì)外提供的接口:
- PluginModuleCallbacks為插件模塊對(duì)外提供的回調(diào)接口,插件管理模塊通過該回調(diào)接口列表與每一個(gè)插件模塊進(jìn)行交互,每一個(gè)新增插件都需要實(shí)現(xiàn)該接口列表中的函數(shù)。
表 1 PluginModuleCallbacks接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()PluginModuleCallbacks::onPluginSessionStart | []()[]()int (PluginSessionStartCallback)(const uint8_tconfigData, uint32_t configSize); | []()[]()- 功能: |
[]()[]()插件會(huì)話開始接口,開始插件會(huì)話時(shí)會(huì)被調(diào)用,用來(lái)下發(fā)插件配置
- 輸入參數(shù):
[]()[]()configData:配置信息內(nèi)存塊起始地址
[]()[]()configSize:配置信息內(nèi)存塊字節(jié)數(shù) - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()PluginModuleCallbacks::onPluginReportResult | []()[]()int (PluginReportResultCallback)(uint8_t bufferData, uint32_t bufferSize); | []()[]()- 功能:
[]()[]()插件結(jié)果上報(bào)接口類型,當(dāng)任務(wù)下發(fā)后,框架采集任務(wù)會(huì)周期性調(diào)用此接口請(qǐng)求回填數(shù)據(jù) - 輸入?yún)?shù):
[]()[]()bufferData: 存放結(jié)果的內(nèi)存緩沖區(qū)起始地址
[]()[]()bufferSize: 存放結(jié)果的內(nèi)存緩沖區(qū)的字節(jié)數(shù) - 返回值:
[]()[]()大于0:已經(jīng)填充的內(nèi)存字節(jié)數(shù)
[]()[]()等于0:沒有填充任何內(nèi)容
[]()[]()小于0:失敗 |
| []()[]()PluginModuleCallbacks::onPluginSessionStop | []()[]()int (*PluginSessionStopCallback)(); | []()[]()- 功能:
[]()[]()采集會(huì)話結(jié)束接口 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()PluginModuleCallbacks::onRegisterWriterStruct | []()[]()int (RegisterWriterStructCallback)(WriterStruct writer); | []()[]()- 功能:
[]()[]()采集框架注冊(cè)寫數(shù)據(jù)接口,當(dāng)插件管理模塊向插件注冊(cè)此接口,插件可以主動(dòng)調(diào)用write句柄,進(jìn)行寫入數(shù)據(jù) - 輸入?yún)?shù):
[]()[]()writer 寫者指針 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 | - WriterStruct是上面onRegisterWriterStruct接口中的參數(shù),主要實(shí)現(xiàn)寫數(shù)據(jù)接口,將插件中采集的數(shù)據(jù)通過該接口進(jìn)行寫入。
表 2 WriterStruct接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()WriterStruct::write | []()[]()long (WriteFuncPtr)(WriterStructwriter, const void* data, size_t size); | []()[]()- 功能: |
[]()[]()寫接口,將插件中采集的數(shù)據(jù)通過writer進(jìn)行寫入
- 輸入?yún)?shù):
[]()[]()writer:寫者指針
[]()[]()data:數(shù)據(jù)緩沖區(qū)首字節(jié)指針
[]()[]()size: 數(shù)據(jù)緩沖區(qū)的字節(jié)數(shù) - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()WriterStruct::flush | []()[]()bool (FlushFuncPtr)(WriterStruct writer); | []()[]()- 功能:
[]()[]()觸發(fā)數(shù)據(jù)上傳接口 - 輸入?yún)?shù):
[]()[]()writer:寫者指針 - 返回值:
[]()[]()true:成功
[]()[]()false:失敗 | - 下面是插件模塊對(duì)外提供的總?cè)肟?,主要包括?中的插件模塊回調(diào)函數(shù)以及插件名稱、插件模塊需要申請(qǐng)的內(nèi)存大小。
表 3 PluginModuleStruct接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()PluginModuleStruct::callbacks | []()[]()PluginModuleCallbacks* | []()[]()功能:定義插件回調(diào)函數(shù)列表 |
[]()[]()PluginModuleStruct::name | []()[]()C style string | []()[]()功能:定義插件名稱 |
[]()[]()PluginModuleStruct::resultBufferSizeHint | []()[]()uint32_t | []()[]()功能:用于提示插件管理模塊調(diào)用數(shù)據(jù)上報(bào)接口時(shí)使用的內(nèi)存緩沖區(qū)字節(jié)數(shù) |
使用說明
下面介紹在設(shè)備端基于性能調(diào)優(yōu)框架提供的插件能力,新增一個(gè)插件涉及到的關(guān)鍵開發(fā)步驟:
- 編寫proto數(shù)據(jù)定義文件_plugin_data.proto_,定義數(shù)據(jù)源格式,數(shù)據(jù)源格式?jīng)Q定了插件上報(bào)哪些數(shù)據(jù):
message PluginData { int32 pid = 1; string name = 2; uint64 count1 = 3; uint64 count2 = 4; uint64 count3 = 5; ...... }
- 編寫數(shù)據(jù)源配置文件_plugin_config.proto_,采集的行為可以根據(jù)配置進(jìn)行變化,可以設(shè)置數(shù)據(jù)源上報(bào)間隔等信息:
message PluginConfig { int32 pid = 1; bool report_interval = 2; int report_counter_id_1 = 3; int report_counter_id_2 = 4; ...... }
- 定義PluginModuleCallbacks實(shí)現(xiàn)插件回調(diào)接口;定義PluginModuleStruct類型的g_pluginModule全局變量,注冊(cè)插件信息。
static PluginModuleCallbacks callbacks = { PluginSessionStart, PluginReportResult, PluginSessionStop, }; PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
- 通過PluginSessionStart(名字可以自己定義)實(shí)現(xiàn)插件回調(diào)接口列表的onPluginSessionStart接口,主要處理插件的開始流程。
int PluginSessionStart(const uint8_t* configData, uint32_t configSize) { ...... return 0; }
- 通過PluginReportResult(名字可以自己定義)實(shí)現(xiàn)插件回調(diào)接口列表的onPluginReportResult接口,將插件內(nèi)部采集的信息通過該接口進(jìn)行上報(bào):
int PluginReportResult(uint8_t* bufferData, uint32_t bufferSize) { ...... return 0; }
- 通過PluginSessionStop(名字可以自己定義)實(shí)現(xiàn)插件回調(diào)接口列表的onPluginSessionStop接口,主要進(jìn)行插件停止后的操作流程。
int PluginSessionStop() { ...... return 0; }
- 編寫proto gn構(gòu)建腳本, 生成protobuf源文件,protobuf源文件編譯生成目標(biāo)文件:
action("plugin_cpp_gen") { script = "${OHOS_PROFILER_DIR}/build/protoc.sh" //依賴的編譯工具鏈 sources = [ //定義的插件相關(guān)的proto文件,比如插件配置文件、插件數(shù)據(jù)對(duì)應(yīng)的proto文件 "plugin_data.proto", "plugin_config.proto", ] outputs = [ //通過protoc編譯生成的結(jié)果文件 "plugin_data.pb.h", "plugin_data.pb.cc", "plugin_config.pb.h", "plugin_config.pb.cc", ] args = [ "--cpp_out", "$proto_rel_out_dir", "--proto_path", rebase_path(".", root_build_dir), ] deps = [ "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc(${host_toolchain})", ] } ohos_source_set("plug_cpp") { //將定義的proto文件生成cpp文件 deps = [ ":plugin_cpp_gen", ] public_deps = [ "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf", "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite", ] include_dirs = [ "$proto_out_dir" ] sources = [ //目標(biāo)plug_cpp中包括的源文件 "plugin_data.pb.h", "plugin_data.pb.cc", "plugin_config.pb.h", "plugin_config.pb.cc", ] }
- 編寫插件GN構(gòu)建腳本:
ohos_shared_library("***plugin") { output_name = "***plugin" sources = [ "src/***plugin.cpp", //插件中的源文件 ] include_dirs = [ "../api/include", "${OHOS_PROFILER_DIR}/device/base/include", ] deps = [ "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite", "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib", "${OHOS_PROFILER_DIR}/protos/types/plugins/**:plug_cpp", //上面ohos_source_set中生成的plug_cpp ] install_enable = true subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" }
調(diào)測(cè)驗(yàn)證:
插件動(dòng)態(tài)庫(kù)生成后,可以自己編寫測(cè)試代碼,通過dlopen加載動(dòng)態(tài)庫(kù),并調(diào)用上面代碼中實(shí)現(xiàn)的插件模塊回調(diào)函數(shù)進(jìn)行驗(yàn)證。
int main(int argc, char** argv)
{
void* handle;
PluginModuleStruct* memplugin;
handle = dlopen("./libplugin.z.so", RTLD_LAZY); //動(dòng)態(tài)打開上面生成的插件動(dòng)態(tài)庫(kù)
if (handle == nullptr) {
HILOGD("dlopen err:%s.", dlerror());
return 0;
}
memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); //獲取開發(fā)步驟3中定義的g_pluginModule全局變量
//check memplugin- >callbacks // 通過該指針調(diào)用上面開發(fā)步驟3中定義的回調(diào)函數(shù)
return 0;
hiprofiler_cmd 使用說明
參數(shù)說明
執(zhí)行hiprofiler_cmd 為調(diào)優(yōu)業(yè)務(wù)的離線命令行抓取工具,具體使用方法及命令行參數(shù)介紹如下。
可以使用-h
或者--help
參數(shù)查看命令的使用描述信息:
hiprofiler_cmd -h
help :
--getport -q : get grpc address
--time -t : trace time
--out -o : output file name
--help -h : make some help
--list -l : plugin list
--start -s : start dependent process
--kill -k : kill dependent process
--config -c : start trace by config file
其余參數(shù)使用說明如下:
-q
或者--getport
選項(xiàng),用于查詢服務(wù)的端口信息;-t
或者--time
選項(xiàng),用于指定抓取時(shí)間,單位是秒;-o
或者--out
選項(xiàng),用于指定輸出的離線數(shù)據(jù)文件名;-h
或者--help
選項(xiàng),用于輸出幫助信息;-l
或者--list
選項(xiàng),用于查詢插件列表;-s
或者--start
選項(xiàng),用于啟動(dòng)依賴的進(jìn)程;-k
或者--kill
選項(xiàng),用于關(guān)閉依賴的進(jìn)程;-c
或者--config
選項(xiàng),用于指定配置文件;
命令展示
基礎(chǔ)配置參數(shù)
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
命令參數(shù)說明:
- request_id:本次請(qǐng)求的id
- pages:存儲(chǔ)trace數(shù)據(jù)的buffer大?。? * pages kb)
- result_file:結(jié)果輸出的文件路徑,與-o參數(shù)對(duì)應(yīng)
- sample_duration:抓取時(shí)長(zhǎng)(ms),與-t參數(shù)對(duì)應(yīng)
ftrace抓取場(chǎng)景示例
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
命令參數(shù)說明:
- sample_interval:輪循模式下,插件上報(bào)數(shù)據(jù)的間隔時(shí)間(ms)
- trace_period_ms:ftrace插件讀取內(nèi)核緩沖區(qū)數(shù)據(jù)的間隔時(shí)間(ms)
- hitrace_time:hitrace命令行抓取時(shí)間,與hiprofiler_cmd下發(fā)的-t配置聯(lián)動(dòng)
內(nèi)存信息抓取場(chǎng)景示例
內(nèi)核內(nèi)存信息
使用如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
虛擬內(nèi)存統(tǒng)計(jì)
使用如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
進(jìn)程內(nèi)存使用跟蹤
如配置抓取的進(jìn)程名是com.ohos.mms
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
配置參數(shù)說明:
- pid/process_name:設(shè)置抓取的進(jìn)程ID或者進(jìn)程名
- max_stack_depth:抓取的棧的深度
- smb_pages:native_daemon和native_hook進(jìn)程之間存儲(chǔ)數(shù)據(jù)的共享內(nèi)存大小(4KB的倍數(shù))
- filter_size:只抓取大于該size的malloc數(shù)據(jù)(free不受影響)
bytrace/hitrace場(chǎng)景示例
運(yùn)行如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 30
-s
<
hiperf場(chǎng)景示例
運(yùn)行如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
審核編輯 黃宇
-
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4314瀏覽量
85851 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3025瀏覽量
74054 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2352瀏覽量
42859
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論