developtools_profiler/README_zh.md
2021-06-02 02:20:20 +08:00

21 KiB
Executable File
Raw Blame History

性能调优组件

简介

性能调优组件包含系统和应用调优框架,旨在为开发者提供一套性能调优平台,可以用来分析内存、性能等问题。

该组件整体分为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接口列表

接口名

类型

描述

PluginModuleCallbacks::onPluginSessionStart

int (*PluginSessionStartCallback)(const uint8_t* configData, uint32_t configSize);

  • 功能:

    插件会话开始接口,开始插件会话时会被调用,用来下发插件配置

  • 输入参数:

    configData配置信息内存块起始地址

    configSize配置信息内存块字节数

  • 返回值:

    0成功

    -1失败

PluginModuleCallbacks::onPluginReportResult

int (*PluginReportResultCallback)(uint8_t* bufferData, uint32_t bufferSize);

  • 功能:

    插件结果上报接口类型,当任务下发后,框架采集任务会周期性调用此接口请求回填数据

  • 输入参数:

    bufferData: 存放结果的内存缓冲区起始地址

    bufferSize: 存放结果的内存缓冲区的字节数

  • 返回值:

    大于0已经填充的内存字节数

    等于0没有填充任何内容

    小于0失败

PluginModuleCallbacks::onPluginSessionStop

int (*PluginSessionStopCallback)();

  • 功能:

    采集会话结束接口

  • 返回值:

    0成功

    -1失败

PluginModuleCallbacks::onRegisterWriterStruct

int (*RegisterWriterStructCallback)(WriterStruct* writer);

  • 功能:

    采集框架注册写数据接口当插件管理模块向插件注册此接口插件可以主动调用write句柄进行写入数据

  • 输入参数:

    writer 写者指针

  • 返回值:

    0成功

    -1失败

  • WriterStruct是上面onRegisterWriterStruct接口中的参数主要实现写数据接口将插件中采集的数据通过该接口进行写入。

表 2 WriterStruct接口列表

接口名

类型

描述

WriterStruct::write

long (*WriteFuncPtr)(WriterStruct* writer, const void* data, size_t size);

  • 功能:

    写接口将插件中采集的数据通过writer进行写入

  • 输入参数:

    writer写者指针

    data数据缓冲区首字节指针

    size: 数据缓冲区的字节数

  • 返回值:

    0成功

    -1失败

WriterStruct::flush

bool (*FlushFuncPtr)(WriterStruct* writer);

  • 功能:

    触发数据上传接口

  • 输入参数:

    writer写者指针

  • 返回值:

    true成功

    false失败

  • 下面是插件模块对外提供的总入口主要包括表1中的插件模块回调函数以及插件名称、插件模块需要申请的内存大小。

表 3 PluginModuleStruct接口列表

接口名

类型

描述

PluginModuleStruct::callbacks

PluginModuleCallbacks*

功能:定义插件回调函数列表

PluginModuleStruct::name

C style string

功能:定义插件名称

PluginModuleStruct::resultBufferSizeHint

uint32_t

功能:用于提示插件管理模块调用数据上报接口时使用的内存缓冲区字节数

使用说明

下面介绍在设备端基于性能调优框架提供的插件能力,新增一个插件涉及到的关键开发步骤:

  1. 编写proto数据定义文件_plugin_data.proto_定义数据源格式数据源格式决定了插件上报哪些数据

    message PluginData {
        int32 pid = 1;
        string name = 2;
        uint64 count1 = 3;
        uint64 count2 = 4;
        uint64 count3 = 5;
        ......
    }
    
  2. 编写数据数据源配置文件_plugin_config.proto_采集的行为可以根据配置进行变化可以设置数据源上报间隔等信息

    message PluginConfig {
        int32 pid = 1;
        bool report_interval = 2;
        int report_counter_id_1 = 3;
        int report_counter_id_2 = 4;
        ......
    }
    
  3. 定义PluginModuleCallbacks实现插件回调接口定义PluginModuleStruct类型的g_pluginModule全局变量注册插件信息。

    static PluginModuleCallbacks callbacks = {
        PluginSessionStart,
        PluginReportResult,
        PluginSessionStop,
    };
    PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
    
  4. 通过PluginSessionStart名字可以自己定义实现插件回调接口列表的onPluginSessionStart接口主要处理插件的开始流程。

    int PluginSessionStart(const uint8_t* configData, uint32_t configSize)
    {
        ......
        return 0;
    } 
    
  5. 通过PluginReportResult名字可以自己定义实现插件回调接口列表的onPluginReportResult接口将插件内部采集的信息通过该接口进行上报

    int PluginReportResult(uint8_t* bufferData, uint32_t bufferSize)
    {
        ......
        return 0;
    } 
    
  6. 通过PluginSessionStop名字可以自己定义实现插件回调接口列表的onPluginSessionStop接口主要进行插件停止后的操作流程。

    int PluginSessionStop()
    {
        ......
        return 0;
    }
    
  7. 编写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",
      ]
    }
    
  8. 编写插件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