---
title: 性能分析过程
description: "- 服务器和操作系统正常运行。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/profiler/demo/kunpengsptpypractice_top-down_0002.html
sourcePath: /source/zh/kunpengdevps/profiler/demo/kunpengsptpypractice_top-down_0002.html
indexId: c2d09ed83b52c0d2ce97433b530e143079f3ff5b9337f34f5a8864a8f7fd5a1977
---
# 性能分析过程

#### 前提条件

- 服务器和操作系统正常运行。
- PC端已经安装SSH远程登录工具。
- 目标环境上鲲鹏性能定界工具、系统性能分析工具已经安装完成，并正常运行。


#### 操作步骤

1. 从GitHub(https://github.com/kunpengcompute/devkitdemo/tree/main/Hyper_tuner/testdemo/CPU分支预测)下载cpu_branch_prediction_before.cpp文件，上传到“/home/demo”目录，执行如下命令切换至源码目录。

```
cd /home/demo
```


2. 编译源码文件。

```
g++ -o cpu_branch_prediction_before cpu_branch_prediction_before.cpp
```


3. 查看应用运行时间。

```
time /home/demo/cpu_branch_prediction_before
```


  执行命令后，发现应用的运行时间为61秒。可使用鲲鹏性能定界工具定位应用有无性能问题，若应用中确实存在优化项则优化源代码。当前应用运行时间作为时间开销的基线。

  运行结果可能因环境不同而产生差异，属于正常情况。

  图1 运行时间

4. 使用鲲鹏性能定界工具定位问题。
  将鲲鹏性能定界工具压缩包上传到“/home”
  目录并解压，解压后进入鲲鹏性能定界工具安装目录，xxx指版本号，请根据实际情况替换。

```
cd /home/ksys-
x.x.x
-Linux-aarch64
```


5. 采集应用的性能数据。

```
./ksys collect /home/demo/cpu_branch_prediction_before
```


  /home/demo/cpu_branch_prediction_before：指定采集的应用。

  图2 微架构统计数据

  在微架构统计数据部分，可以看出Bad Speculation(%)中的Branch Mispredicts(%)较高，Branch Mispredicts即分支预测错误，该指标的数值是指在程序运行期间CPU发生了多少次分支预测错误。在CPU流水线中，一次分支预测错误会带来较大的时间开销，即Branch Mispredicts指标越高，分支预测失败次数越多，CPU额外开销越大，对应性能越差。鲲鹏性能定界工具采集的Topdown指标是系统性能分析工具微架构分析采集的子集，想要看到更详细的指标推荐使用系统性能分析工具的微架构分析。

6. 使用系统性能分析工具进一步分析程序。
  将系统性能分析工具压缩包上传到“/home”
  目录并解压，解压后切换至系统性能分析工具安装目录，xxx指版本号，请根据实际情况替换。

```
cd /home/DevKit-Tuner-CLI-
x.x.x
-Linux-aarch64
```


7. 使用系统性能分析工具对应用进行微架构分析。

```
./devkit tuner top-down -d 30 /home/demo/cpu_branch_prediction_before
```


  -d 30：指定采集时间为30秒。 /home/demo/cpu_branch_prediction_before：指定采集的应用。

  图3 微架构分析报告

  查看微架构分析报告，发现其中Branch Mispredicts下的Other Branch占比较高，也就是Branch Mispredicts占比高，与鲲鹏性能定界工具定位结果相同，说明程序中CPU分支预测失败较多，需关注源代码中的条件跳转/无条件直接跳转。

  每种Branch对应含义以及常见源代码使用场景： Indirect Branch：间接分支。跳转目标地址不是立即数，而是来自寄存器或者内存，常见于虚函数、函数指针、switch跳转表。 Push Branch：入栈分支。对应x86的汇编命令为call，对应Arm的汇编命令为bl，常见于函数的调用。 Pop Branch：出栈分支。对应x86和Arm的汇编命令为ret，常见于函数的返回。 Other Branch：其他分支。条件跳转和无条件直接跳转，常见于if-else/for/while/do-while/三元运算符/break/continue/goto等代码。

8. 查看源码文件，确定源码问题。

```
vim /home/demo/cpu_branch_prediction_before.cpp
```


  图4 源码文件

  源码中对生成的每个随机数都进行if-else判断，在生成的随机数没有进行排序时，CPU分支预测失败率较高，频繁切换策略导致耗时较长。
