1# 使用HiTraceMeter跟踪性能(C/C++) 2 3## 简介 4 5HiTraceMeter提供系统性能打点接口。开发者通过在关键代码位置调用HiTraceMeter接口提供的API接口,能够有效跟踪进程轨迹、查看系统性能。 6 7## 基本概念 8 9**HiTraceMeter Tag**:跟踪数据使用类别,称作HiTraceMeter Tag,一般每个软件子系统对应一个tag。[hitrace](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/dfx/hitrace.md)命令行工具采集跟踪数据时,只采集给定的tag类别选项指定的跟踪数据。应用中的HiTraceMeter打点的tag是HITRACE_TAG_APP,对应[hitrace](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/dfx/hitrace.md)命令`hitrace -l`列出的tag列表中的app。 10 11## 实现原理 12 131. 应用程序通过HiTraceMeter函数接口进行打点,HiTraceMeter函数将跟踪数据通过内核sysfs文件接口输入到内核的ftrace数据缓冲区。 142. [hitrace](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/dfx/hitrace.md)命令行工具读取内核ftrace缓冲区中的跟踪数据,将跟踪数据输出到设备侧的文件中。 15 16## 接口说明 17 18性能打点跟踪接口由HiTraceMeter模块提供,详细API请参考[性能打点跟踪API参考](../reference/apis-performance-analysis-kit/_hitrace.md)。 19 20| 方法 | 接口描述 | 21| ------------------------------------------------------------ | -------------------------- | 22| void OH_HiTrace_StartTrace(const char* name) | 开启一个同步时间片跟踪事件 | 23| void OH_HiTrace_FinishTrace() | 结束一个同步时间片跟踪事件 | 24| void OH_HiTrace_StartAsyncTrace(const char* name, int32_t taskId) | 开启一个异步时间片跟踪事件 | 25| void OH_HiTrace_FinishAsyncTrace(const char* name, int32_t taskId) | 结束一个异步时间片跟踪事件 | 26| void OH_HiTrace_CountTrace(const char* name, int64_t count) | 整数跟踪事件 | 27 28> **注意:** 29> 30> 用户态tarce格式使用竖线 `|` 作为分隔符,所以通过HiTraceMeter接口传递的字符串类型参数应避免包含该字符,防止trace解析异常。 31 32HiTraceMeter打点接口按功能/行为分类,主要分三类:同步时间片跟踪接口、异步时间片跟踪接口和整数跟踪接口。无论同步时间片跟踪接口还是异步时间片跟踪接口,接口本身都是同步接口,不是异步接口。HiTraceMeter打点接口可与[HiTraceChain](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/dfx/hitracechain-guidelines-arkts.md)一起使用,进行跨设备/跨进程/跨线程打点与分析。 33 34- 同步时间片跟踪接口用于顺序执行的打点场景。 35- 异步时间片跟踪接口用于在异步操作执行前进行开始打点,在异步操作完成后进行结束打点。异步跟踪的开始和结束由于不是顺序发生的,解析trace时需要通过name与taskId参数进行识别,name与taskId参数相同的异步跟踪开始与结束打点相匹配。 36- 整数跟踪接口用于跟踪整数变量。 37 38**参数解析** 39 40| 参数名 | 类型 | 必填 | 说明 | 41| ------ | ------ | ---- | ------------------------------------------------------------ | 42| name | string | 是 | 要跟踪的数值变量名称。 | 43| taskId | number | 是 | 用来表示关联的ID,如果有多个name相同的任务是并行执行的,则每次调用startTrace的taskId不同。 | 44| count | number | 是 | 变量的值。 | 45 46## 开发示例 47 48在DevEco Studio中创建Native C++工程,使用HiTraceMeter NDK_C打点接口,以下为一个Native C++工程示例。 49 501. 新建一个Native C++工程,工程目录结构如下: 51 52 ```text 53 ├── entry 54 │ ├── src 55 │ ├── main 56 │ │ ├── cpp 57 │ │ │ ├── CMakeLists.txt 58 │ │ │ ├── napi_init.cpp 59 │ │ │ └── types 60 │ │ │ └── libentry 61 │ │ │ ├── Index.d.ts 62 │ │ │ └── oh-package.json5 63 │ │ ├── ets 64 │ │ │ ├── entryability 65 │ │ │ │ └── EntryAbility.ets 66 │ │ │ ├── entrybackupability 67 │ │ │ │ └── EntryBackupAbility.ets 68 │ │ │ └── pages 69 │ │ │ └── Index.ets 70 ``` 71 722. 在"CMakeLists.txt"文件末尾新增如下内容,添加libhitrace_ndk.z.so和libhilog_ndk.z.so动态链接库。 73 74 ```cmake 75 target_link_libraries(entry PUBLIC libhitrace_ndk.z.so libhilog_ndk.z.so) 76 ``` 77 783. 编辑"napi_init.cpp"文件,在Add函数中调用HiTraceMeter NDK_C的接口,进行性能打点跟踪, 示例代码如下: 79 80 ```c++ 81 #include "hilog/log.h" 82 #include "hitrace/trace.h" 83 #include "napi/native_api.h" 84 85 #undef LOG_TAG 86 #define LOG_TAG "traceTest" 87 88 static napi_value Add(napi_env env, napi_callback_info info) 89 { 90 // 第一个异步跟踪任务开始 91 OH_HiTrace_StartAsyncTrace("myTestAsyncTrace", 1001); 92 // 开始计数任务 93 int64_t traceCount = 0; 94 traceCount++; 95 OH_HiTrace_CountTrace("myTestCountTrace", traceCount); 96 // 业务流程 97 OH_LOG_INFO(LogType::LOG_APP, "myTraceTest running, taskId: 1001"); 98 99 // 第二个异步跟踪任务开始,同时第一个跟踪的同名任务还没结束,出现了并行执行,对应接口的taskId需要不同 100 OH_HiTrace_StartAsyncTrace("myTestAsyncTrace", 1002); 101 // 开始计数任务 102 traceCount++; 103 OH_HiTrace_CountTrace("myTestCountTrace", traceCount); 104 // 业务流程 105 OH_LOG_INFO(LogType::LOG_APP, "myTraceTest running, taskId: 1002"); 106 107 // 结束taskId为1001的异步跟踪任务 108 OH_HiTrace_FinishAsyncTrace("myTestAsyncTrace", 1001); 109 // 结束taskId为1002的异步跟踪任务 110 OH_HiTrace_FinishAsyncTrace("myTestAsyncTrace", 1002); 111 112 // 开始同步跟踪任务 113 OH_HiTrace_StartTrace("myTestSyncTrace"); 114 // 业务流程 115 OH_LOG_INFO(LogType::LOG_APP, "myTraceTest running, synchronizing trace"); 116 // 结束同步跟踪任务 117 OH_HiTrace_FinishTrace(); 118 119 size_t requireArgc = 2; 120 size_t argc = 2; 121 napi_value args[2] = {nullptr}; 122 123 napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 124 125 napi_valuetype valuetype0; 126 napi_typeof(env, args[0], &valuetype0); 127 128 napi_valuetype valuetype1; 129 napi_typeof(env, args[1], &valuetype1); 130 131 double value0; 132 napi_get_value_double(env, args[0], &value0); 133 134 double value1; 135 napi_get_value_double(env, args[1], &value1); 136 137 napi_value sum; 138 napi_create_double(env, value0 + value1, &sum); 139 140 return sum; 141 } 142 143 EXTERN_C_START 144 static napi_value Init(napi_env env, napi_value exports) 145 { 146 napi_property_descriptor desc[] = { 147 { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr } 148 }; 149 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 150 return exports; 151 } 152 EXTERN_C_END 153 154 static napi_module demoModule = { 155 .nm_version = 1, 156 .nm_flags = 0, 157 .nm_filename = nullptr, 158 .nm_register_func = Init, 159 .nm_modname = "entry", 160 .nm_priv = ((void*)0), 161 .reserved = { 0 }, 162 }; 163 164 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) 165 { 166 napi_module_register(&demoModule); 167 } 168 ``` 169 1704. 在DevEco Studio Terminal窗口中执行如下命令,开启应用trace捕获: 171 172 ```shell 173 PS D:\xxx\xxx> hdc shell 174 $ hitrace --trace_begin app 175 ``` 176 1775. 单击DevEco Studio界面上的运行按钮,启动应用,点击屏幕中间的字符串,执行包含HiTraceMeter打点的业务逻辑,然后执行如下命令抓取trace数据: 178 179 ```shell 180 $ hitrace --trace_dump | grep myTest 181 ``` 182 183 成功抓取的trace数据如下所示: 184 185 ```text 186 <...>-21458 (-------) [009] .... 372404.331037: tracing_mark_write: S|21458|H:myTestAsyncTrace|1001 187 <...>-21458 (-------) [009] .... 372404.331040: tracing_mark_write: C|21458|H:myTestCountTrace|1 188 <...>-21458 (-------) [009] .... 372404.331083: tracing_mark_write: S|21458|H:myTestAsyncTrace|1002 189 <...>-21458 (-------) [009] .... 372404.331085: tracing_mark_write: C|21458|H:myTestCountTrace|2 190 <...>-21458 (-------) [009] .... 372404.331091: tracing_mark_write: F|21458|H:myTestAsyncTrace|1001 191 <...>-21458 (-------) [009] .... 372404.331093: tracing_mark_write: F|21458|H:myTestAsyncTrace|1002 192 <...>-21458 (-------) [009] .... 372404.331095: tracing_mark_write: B|21458|H:myTestSyncTrace 193 ``` 194 1956. 执行如下命令,结束应用trace捕获: 196 197 ```shell 198 $ hitrace --trace_finish 199 ``` 200