如何获取Adreno GPU数据

什么是GPU

        GPU(Graphic Processing Unit)是图形处理器,相当于在计算机和移动终端上做图形图像运算工作的微处理器,显示芯片。通过向量计算和并行计算等方式加速了原有的计算工作,能够更好地处理几何转换和光照计算等,更是在深度学习领域起着不可或缺的作用。

什么是Adreno GPU

        Adreno GPU为采用了骁龙处理器的移动终端提供游戏机品质的3D图形处理能力,为游戏、用户界面和高性能计算任务提供更快的图形处理。

如何获取Adreno GPU性能数据

1. 使用Adreno profiler

链接:Adreno GPU Profiler - Qualcomm Developer Network

高通官方提供了对应的Profiler 工具,不过具体的内容并没有开源,如果需要实时获取profiler性能还是推荐直接使用官方的工具。

2. 使用第三方库

链接:https://github.com/google/hardware-perfcounter

在这个Hardware-perfcounter里面,通过对一些工具的解析,能够通过cycle获取基础的GPU数据,从而帮助开发者更好地实时记录需要关注的GPU内容。

具体操作

这边只需要获取adreno gpu数据,因此对于库中所使用的mali gpu就不加赘述了。

准备工具:

cmake 版本大于3.13

g++ 或者 gcc 能够编译 c11/c++14的

ninja 

1. 先git clone GitHub - google/hardware-perfcounter: libraries and tilities for sampling hardware performance counterslibraries and utilities for sampling hardware performance counters - GitHub - google/hardware-perfcounter: libraries and utilities for sampling hardware performance countershttps://github.com/google/hardware-perfcounter.git

到本地文件夹,然后进入到third_party,这边对envytools有依赖,所以需要拉取里面的内容,同样的使用git工具 clone
GitHub - freedreno/envytoolsContribute to freedreno/envytools development by creating an account on GitHub.https://github.com/freedreno/envytools.git

2. 直接build就行了。

Android

git clone https://github.com/google/HardwarePerfCounter.git
cd HardwarePerfCounter

cmake -G Ninja -S ./ -B build-android/  \
  -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK?}/build/cmake/android.toolchain.cmake" \
  -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-30
cmake --build build-android/

Linux/macOS

git clone https://github.com/google/HardwarePerfCounter.git
cd HardwarePerfCounter

cmake -G Ninja -S ./ -B build/
cmake --build build/

 Windows

在Git网页上说明尚且不支持windows,应该是尚且不支持在windows操作系统执行获取gpu数据,编译方法同Linux/macOS,在Powershell/cmd执行对应的操作即可。

3. 具体使用方式

比如我build到android上,那么就会在build-android/examples内部出现多个example执行文件,这边adreno分为common, a5xx和a6xx三种,假设对应手机是iQOO 8,使用的是Adreno 660, 那么就执行

adb push adreno_a6xx_c_example /data/local/tmp

adb shell
cd /data/local/tmp
./adreno_a6xx_c_example

这样就能够获取示例所输出的内容。

解读示例

打开examples/adreno_a6xx_example.c文件,我们可以看到具体是如何获取的。

在a6xx.h文件中可以看到,库的作者做了不少工作,将对应内容的counter号所代表的含义已经通过enum标记好了,同时,封装好了如下几个方法:

//创建context
int hpc_gpu_adreno_a6xx_create_context(
    uint32_t num_counters, hpc_gpu_adreno_a6xx_counter_t *counters,
    const hpc_gpu_host_allocation_callbacks_t *allocator,
    hpc_gpu_adreno_context_t **out_context);


//销毁context
int hpc_gpu_adreno_a6xx_destroy_context(
    hpc_gpu_adreno_context_t *context,
    const hpc_gpu_host_allocation_callbacks_t *allocator);

//开始counter
int hpc_gpu_adreno_a6xx_start_counters(const hpc_gpu_adreno_context_t *context);


//停止counter
int hpc_gpu_adreno_a6xx_stop_counters(const hpc_gpu_adreno_context_t *context);


//获取counter
int hpc_gpu_adreno_a6xx_query_counters(hpc_gpu_adreno_context_t *context,
                                       uint64_t *values);

1. 首先定义好counter数组,数组内部对应的enum值为需要获取的数值。

2. 创建context, 并且使用对应的context开启counter

3. 通过query_counter的操作获取对应的数值,数值对应步骤1的counter数组

4. 停止counter同时销毁context.

那么,Query 又是如何获取counter的呢?还是通过查看源码,我们最终可以知道,调用的是ioctl的方法来读取对应counter数值。

int hpc_gpu_adreno_ioctl_query_counters(
    int gpu_device, uint32_t num_counters,
    hpc_gpu_adreno_ioctl_counter_read_counter_t *counters, uint64_t *values) {
  struct adreno_counter_read payload;
  memset(&payload, 0, sizeof(struct adreno_counter_read));
  payload.num_counters = num_counters;
  payload.counters = counters;

  int status = ioctl(gpu_device, ADRENO_IOCTL_COUNTER_READ, &payload);
  if (status) return status;

  for (int i = 0; i < num_counters; ++i) values[i] = counters[i].value;

  return 0;
}

linux 内核 - ioctl 函数详解 - 知乎1. 概念ioctl 是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设 ioctl() 命令的方式实现。 在文件 I/O 中…https://zhuanlan.zhihu.com/p/478259733具体涉及到linux内核,类似操作应该是和写驱动的方法一样,此处就不长篇大论了。

注意事项

在博主具体操作过程中发现,当我使用perfmance-counter采集骁龙处理器的gpucounter时,当counter数组中含有的enum大于6时,后续数字经常会出错或为0。这边是每次通过gpu cycle就获取counter数组量的数值速度太慢,来不及获取已经更新。因此具体使用时建议在每次调用query时获取的counter数据尽量保持在6个以内。

猜你喜欢

转载自blog.csdn.net/u013379032/article/details/128087376