鸿蒙开源组件——性能调优组件
性能调优组件
简介
性能调优组件包含系统和应用调优框架,旨在为开发者提供一套性能调优平台,可以用来分析内存、性能等问题。
该组件整体分为PC端和设备端两部分,PC端最终作为deveco studio的插件进行发布,内部主要包括分为UI绘制、设备管理、进程管理、插件管理、数据导入、数据存储、 数据分析、Session管理、配置管理等模块;设备端主要包括命令行工具、服务进程、插件集合、应用程序组件等模块。设备端提供了插件扩展能力,对外提供了插件接口,基于该扩展能力可以按需定义自己的能力,并集成到框架中来,目前基于插件能力已经完成了实时内存插件和trace插件。下文会重点对设备端提供的插件能力进行介绍。
架构图
目录
/developtools/profiler
├── device # 设备侧代码目录
│ └── base
│ ├── include # 基础功能的头文件代码目录
│ ├── src # 基础功能的源文件代码目录
│ ├── test # 基础功能的测试代码目录
│ └── cmds
│ ├── include # 对外命令行模块的头文件代码目录
│ ├── src # 对外命令行模块的源文件代码目录
│ ├── test # 对外命令行模块的测试代码目录
│ └── plugins
│ ├── api # 插件模块对外提供的接口文件代码目录
│ └── include # 插件模块对外提供的接口头文件代码目录
│ └── src # 插件模块对外提供的接口源文件代码目录
│ ├── memory_plugin # 内存插件模块代码目录
│ └── include # 内存插件模块头文件代码目录
│ └── src # 内存插件模块源文件代码目录
│ └── test # 内存插件模块测试代码目录
│ ├── trace_plugin # trace插件模块代码目录
│ └── include # trace插件模块头文件代码目录
│ └── src # trace插件模块源文件代码目录
│ └── test # trace插件模块测试代码目录
├── host # 主机侧代码目录
│ └── ohosprofiler # 主机侧调优模块代码目录
│ └── src # 主机侧调优模块源文件代码目录
├── protos # 项目中的proto格式文件的代码目录
│ └── innerkits # 对内部子系统暴露的头文件存放目录
│ └── builtin # JS应用框架对外暴露JS三方module API接口存放目录
├── trace_analyzer # bytrace解析模块的代码目录
│ └── include # bytrace解析模块的公共头文件存放目录
│ └── src # bytrace解析模块功能源文件存放目录
├── interfaces # 项目中接口的代码目录
│ └── innerkits # 模块间接口的代码目录
│ └── kits # 对外提供接口存放目录
说明
下面针对设备端对外提供的插件扩展能力进行接口和使用说明。
接口说明
下面是设备端插件模块对外提供的接口:
- PluginModuleCallbacks为插件模块对外提供的回调接口,插件管理模块通过该回调接口列表与每一个插件模块进行交互,每一个新增插件都需要实现该接口列表中的函数。
表 1 PluginModuleCallbacks接口列表
int (*PluginSessionStartCallback)(const uint8_t* configData, uint32_t configSize); |
||
int (*PluginReportResultCallback)(uint8_t* bufferData, uint32_t bufferSize); |
||
- WriterStruct是上面onRegisterWriterStruct接口中的参数,主要实现写数据接口,将插件中采集的数据通过该接口进行写入。
表 2 WriterStruct接口列表
long (*WriteFuncPtr)(WriterStruct* writer, const void* data, size_t size); |
||
- 下面是插件模块对外提供的总入口,主要包括表1中的插件模块回调函数以及插件名称、插件模块需要申请的内存大小。
表 3 PluginModuleStruct接口列表
使用说明
下面介绍在设备端基于性能调优框架提供的插件能力,新增一个插件涉及到的关键开发步骤:
-
编写proto数据定义文件_plugin_data.proto_,定义数据源格式,数据源格式决定了插件上报哪些数据:
message PluginData { int32 pid = 1; string name = 2; uint64 count1 = 3; uint64 count2 = 4; uint64 count3 = 5; ...... }
- 编写数据数据源配置文件_plugin_config.proto_,采集的行为可以根据配置进行变化,可以设置数据源上报间隔等信息:
message PluginConfig { int32 pid = 1; bool report_interval = 2; int report_counter_id_1 = 3; int report_counter_id_2 = 4; ...... }
- 定义PluginModuleCallbacks实现插件回调接口;定义PluginModuleStruct类型的g_pluginModule全局变量,注册插件信息。
static PluginModuleCallbacks callbacks = { PluginSessionStart, PluginReportResult, PluginSessionStop, }; PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
- 通过PluginSessionStart(名字可以自己定义)实现插件回调接口列表的onPluginSessionStart接口,主要处理插件的开始流程。
int PluginSessionStart(const uint8_t* configData, uint32_t configSize) { ...... return 0; }
- 通过PluginReportResult(名字可以自己定义)实现插件回调接口列表的onPluginReportResult接口,将插件内部采集的信息通过该接口进行上报:
int PluginReportResult(uint8_t* bufferData, uint32_t bufferSize) { ...... return 0; }
- 通过PluginSessionStop(名字可以自己定义)实现插件回调接口列表的onPluginSessionStop接口,主要进行插件停止后的操作流程。
int PluginSessionStop() { ...... return 0; }
- 编写proto gn构建脚本, 生成protobuf源文件,protobuf源文件编译生成目标文件:
action("plugin_cpp_gen") {
script = "${OHOS_PROFILER_DIR}/build/protoc.sh" //依赖的编译工具链
sources = [ //定义的插件相关的proto文件,比如插件配置文件、插件数据对应的proto文件
"plugin_data.proto",
"plugin_config.proto",
]
outputs = [ //通过protoc编译生成的结果文件
"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 = [ //目标plug_cpp中包括的源文件
"plugin_data.pb.h",
"plugin_data.pb.cc",
"plugin_config.pb.h",
"plugin_config.pb.cc",
]
}
编写插件GN构建脚本:
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}"
}
调测验证:
插件动态库生成后,可以自己编写测试代码,通过dlopen加载动态库,并调用上面代码中实现的插件模块回调函数进行验证。
int main(int argc, char** argv)
{
void* handle;
PluginModuleStruct* memplugin;
handle = dlopen("./libplugin.z.so", RTLD_LAZY); //动态打开上面生成的插件动态库
if (handle == nullptr) {
HILOGD("dlopen err:%s.", dlerror());
return 0;
}
memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); //获取开发步骤3中定义的g_pluginModule全局变量
//check memplugin->callbacks // 通过该指针调用上面开发步骤3中定义的回调函数
return 0;
相关仓
研发工具链子系统
developtools_profiler
developtools_hdc_standard
developtools_bytrace_standard