---
title: 示例2：列访问循环检测优化
description: "针对上述二维数组，在内存中是按行顺序排列的，即X00、X01、X02、X03、……、X10、X11、X12、X13……处理器从内存获取数据时，会获取该数据及其他附近共64字节（Cache Line长度）的数据，例如获取X00，实际也会读取X00后面的X01、X02……这样接下来处理器要读取X01的数据时，它就不需要再访问内存了，而直接从Cache中就能获取到。所以，程序按行顺序读取数据，节省了访存的时间，性能就很高。如果按列读取，读取X00时缓存的数据中可能并不包含X10，所以接下来访问X10时，访问缓存失败，又需要访问内存。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/profiler/demo/KunpengDevKitDsug_0022.html
sourcePath: /source/zh/kunpengdevps/profiler/demo/KunpengDevKitDsug_0022.html
indexId: 9830b86317fc5eba117ad8511037718563cfa3f90e7a6eed5257b2af8f75dadf65
---
# 示例2：列访问循环检测优化

#### 简介


针对上述二维数组，在内存中是按行顺序排列的，即X00、X01、X02、X03、……、X10、X11、X12、X13……处理器从内存获取数据时，会获取该数据及其他附近共64字节（Cache Line长度）的数据，例如获取X00，实际也会读取X00后面的X01、X02……这样接下来处理器要读取X01的数据时，它就不需要再访问内存了，而直接从Cache中就能获取到。所以，程序按行顺序读取数据，节省了访存的时间，性能就很高。如果按列读取，读取X00时缓存的数据中可能并不包含X10，所以接下来访问X10时，访问缓存失败，又需要访问内存。


#### 环境准备

1. 请确认服务器上已安装的操作系统是否兼容，GCC版本是否为7.3.0及以上，兼容性请参见DevKit兼容性查询助手(https://www.hikunpeng.com/zh/developer/developtool)。
2. 请确认服务器上是否已安装鲲鹏DevKit系统性能分析工具。
3. 请从GitHub(https://github.com/kunpengcompute/devkitdemo/tree/main/Hyper_tuner/testdemo/cache)下载代码样例，执行以下命令赋予所有用户可读、可写和可执行权限。
  样例代码文件为cache_hit.c、cache_miss.c。

```
chmod 777 cache_hit.c cache_miss.c
```


#### Cache_miss数组访问工具检测

1. 程序准备。
  编译cache_miss.c并赋予执行文件所有用户可读、可写和可执行权限。

```
gcc -g cache_miss.c -o cache_miss && chmod 777 cache_miss
```


2. 采用热点函数分析cache_miss程序，找到热点函数和指令。
  单击系统性能分析后面的，选择“通用分析”，打开新建任务页面，选择“热点函数分析”，参数配置完成后单击“确认”启动热点函数分析任务。

  图1 新建热点函数分析任务

**表1 任务参数配置说明**

| 参数 | 说明 |
| --- | --- |
| 分析类型 | 热点函数分析。 |
| 分析对象 | 应用。本示例分析的热点函数为已确定程序，所以不需在服务器上运行程序，直接在工具中选择cache\_miss程序。 |
| 模式 | Launch application。 |
| 应用路径 | 输入程序所在的绝对路径，例如本示例将代码样例放在服务器“/opt/testdemo/cache/cache\_miss/cache\_miss”目录下。示例路径中的第一个cache\_miss为文件夹，第二个cache\_miss为可执行程序。 |
| 采样时长（s） | 30秒。 |
| 采集调用栈 | 开启。 |
| 采样范围 | 用户态。采样范围分用户态、内核态、所有。因为发现所有的CPU消耗都在用户态，所以只采集用户态的数据。 |
| dwarf | 开启。 |
| C/C++ 源文件目录 | 用于采集过程时关联源码。本示例使用/opt/testdemo/cache/cache\_miss/。 |
| 其他参数 | 默认。 |


3. 查看采集分析结果。
  图2 热点函数分析结果总览

  在下面的热点函数中，可以看到cache_miss程序中的main函数占用了所有的时钟周期数；单击蓝色函数名，可查看源码对应行数。


#### 优化方案

1. 程序准备。
  编译cache_hit.c并赋予执行文件所有用户可读、可写、可执行权限。

```
gcc -g cache_hit.c -o cache_hit && chmod 777 cache_hit
```


2. 采用热点函数分析功能进行分析。
  单击系统性能分析后面的，选择“通用分析”，打开新建任务页面，选择“热点函数分析”，参数配置完成后单击“确认”启动热点函数分析任务。 图3 新建热点函数分析任务 表2 任务参数配置说明 参数 说明 分析类型 热点函数分析。 分析对象 应用。 模式 Launch application。 应用路径 输入程序所在的绝对路径，例如本示例将代码样例放在服务器“/opt/testdemo/cache/cache_hit/cache_hit”目录下。示例路径里面第一个cache_hit为文件夹，第二个cache_hit为可执行程序。 采样时长（s） 30秒。 采集调用栈 开启。 采样范围 用户态。采样范围分用户态、内核态、所有。因为发现所有的CPU消耗都在用户态，所以只采集用户态的数据。 dwarf 开启。 C/C++ 源文件目录 用于采集过程时关联源码。本示例使用/opt/testdemo/cache/cache_hit/。 其他参数 默认。

3. 查看采集分析结果。
  图4 热点函数分析结果总览

  比较cache_hit和cache_miss程序的热点函数分析结果，优化后的程序运行时间和周期数远远小于未优化前的。

  此处数值根据sampling采集数据得来，非绝对值，不同环境的数值可能有较大差别，主要关注优化前后的变化。


#### 结果分析

优化循环体后的cache_hit函数执行时间明显降低。
