高通cDSP简单编程例子(实现查询高通cDSP使用率、签名),RK3588 npu使用率查询

PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

前置说明

  本文作为本人csdn blog的主站的备份。(BlogID=117)

环境说明
  • 高通865 android盒子
  • Hexagon_SDK

前言


  由于业务需求,我们需要展示高通865的cpu/gpu/dsp的使用率,其中cpu/gpu是非常简单的。但是对于dsp来说,我找了许久,才发现了一点点端倪,下面就是这一部分成果。

高通cDSP使用率查询


  要实现高通dsp使用率的查询,我们最开始查询到的一点资料是一个sysmon tools,这个工具在高通的sdk中,这个工具可以查看相关的利用率,所以我们按照这个方向走下去。

安装高通dsp sdk

  去此网站下载sdk并安装(//developer.qualcomm.com/software/hexagon-dsp-sdk/tools) 。注意,安装需要java环境,请自备。

  然后我们需要检查我们的环境配置。

  参考SDK目录中Hexagon_SDK/3.5.4/docs/calculator_c++.html,然后进入Hexagon_SDK\3.5.4\examples\common\calculator_c++目录,编译生成target文件及模拟文件。然后安装教程,将计算器例子拷贝到设备相关目录进行运行,成功得到计算结果。这代表环境配置正确。

  注意:这里可能会有很多问题,多看文档,多对比。特别是设备对应的dsp工具链选对,详情参考:Hexagon_SDK/3.5.4/docs/feature_matrix.html。

  在这一步的计算器例子执行完成之后,基本上,我们应该知道生成的文件有3个,一个是android adb 可执行文件,一个是可执行文件对应的ndk库。一个是ndk库对应的dsp调用so。它们之间的关系是执行可执行文件,查找对应的符号,然后通过fastrpc调用dsp对应的符号,并得到结果。详情参考:Hexagon_SDK/3.5.4/docs/APIs_FastRPC.html#FastRPC%20architecture

高通cDSP使用率查询原理分析

  在Hexagon_SDK\3.5.4\tools\utils\sysmon,当我把sysMon_DSP_Profiler_V2.apk安装到系统后,终于看到了cDSP使用率查询的一丝方法。从图中可知,我们得到了dsp的当前工作频率,以及当前的使用率。但是我的需求是制作一个小工具,能够直接打印出core utilization,所以需要想其他办法。

rep_img

  当我了解到这些内容后,就得把目标放在高通sdk里面的perf相关内容里面,我查询了相关api和文档后(Hexagon_SDK/3.5.4/docs/APIs_DSP%20Clk%20&%20Rsrc%20Mgmt.html),发现了两个相关的内容,DSP Power and Performance Management 以及 HAP PMU framework。但是这个时候,我还是没有办法知道官方的工具里面显示的使用率是怎么算的。最开始:根据文档Hexagon_SDK/3.5.4/docs/images/Hexagon_Document_Bundle.pdf 第9章 processor event symbols,我以为直接用COMMITTED_PKT_ANY及COMMITTED_PKT_SMT就能计算出使用率,但是经过我的分析,怎么算都对不上,这个时候我又把重心转向官方的分析工具,官方的分析工具能够保存数据,然后用官方的其他的工具来后处理之后进行分析,看看能否从这里找到一些相关信息。

  再次使用官方工具分析dsp信息然后保存相关的数据文件,然后dump到windows上,得到sysmon_CDSP.bin,用工具分析。在Hexagon_SDK\3.5.4\tools\utils\sysmon\parser_win_v2 目录有两个工具,一个是解析工具,一个是生成html报告,我们按照官方的方法生成html报告,如下图。

rep_img

  我们打开生成的html报告,我在报告中总算查看到了QDSP6 Utilization和QDSP6 Core performance ,如下图。通过阅读相关含义,了解到了官方app中的core utilization的计算方法。其计算方法为:使用率=(总执行次数/当前频率(hz) * 采样时间(s))* 100。原理解释:总执行次数除以当前频率下满载运行次数,得到使用率。这里的总执行次数由HAP_perf_get_pcycles来得到,当前运行频率由HAP_power_get得到。到此,整个技术上的链条打通了,现在开始编写小程序。

rep_img
高通cDSP编程

  首先,直接复制一个calculator_c++官方例子工程来作为模板,根据我了解到的资料,直接选取makefile作为作为编译手段。通过编写dsp的小程序,然后得到我们的使用率。下面是重要api的展示。

/**
* Data type to retrieve power values from the ADSP
* @param type				-	Identifies the type to retrieve.
* @param max_mips			-	Max mips supported
* @param max_bus_bw			-	Max bus bw supported
* @param client_class		-	Current client class
* @param clkFreqHz			-	Current core CPU frequency
* @param aggregateAVSMpps	-	Aggregate AVS Mpps used by audio and voice
* @param dcvsEnabled		-	Indicates if dcvs is enabled / disabled.
*/
typedef struct {
	HAP_Power_response_type type;
	union{
		unsigned int max_mips;
		uint64 max_bus_bw;
		unsigned int client_class;
		unsigned int clkFreqHz;
		unsigned int aggregateAVSMpps;
		boolean dcvsEnabled;
	};
} HAP_power_response_t;

/**
* Method to retrieve power values from the ADSP
* @param context	-	Ignored
* @param request	-	Response.
*/
int HAP_power_get(void* context, HAP_power_response_t* response);



/* 
  HAP_perf_get_pcycles 
   
  Gets the current 64-bit processor cycle count
   
  The processor cycle count is the current number of processor cycles executed
  since the Hexagon processor was last reset.
 
  Note that this counter stops incrementing whenever the DSP enters a low-power
  state (such as clock gating), as opposed to the qtimer, which increments 
  regardless of the DSP power state.

	
  Returns:
  Integer -- Current count of Hexagon processor cycle count.
*/
uint64 HAP_perf_get_pcycles(void);

  对于我们编写dsp小程序来说,有一个值得注意的地方,这些api虽然我们是在android ndk程序里面调用的,但是我们仅仅是在android ndk侧找到符号,然后通过fastrpc将参数发给dsp端,dsp端调用对应的api后,将结果返回给android ndk端。此部分重点参考前文环境配置部分,对于新手来说,很难理解或者说适应这个东西。

高通cDSP程序部署及签名

  由于高通的cDSP程序调用方式比较特殊,我们应该按照官方Hexagon_SDK/3.5.4/docs/calculator_c++.html例子中推荐的部署方式,如果需要自定义部署,请参考环境变量DSP_LIBRARY_PATH。也就是拷贝android侧文件到对应目录,拷贝dsp侧目录到对应目录。

  此外,当你真的自定义程序并部署使用的时候,会遇到签名问题。在开发阶段,我们都是使用testsign,具体详情参考:Hexagon_SDK/3.5.4/docs/Tools_Signing.html,就是按照官方方法生成一个对应的testsign-xxxx.so的文件,此文件包含了当前设备的id,能够让运行在当前设备上的程序免签。但是这种方法只能够用于调试,对于大规模使用,需要采取另外的部署方式,一种是联系厂家,提供批量签名工具,另外就是使用 Unsigned PD 功能(Unsigned PD is a sandboxed low-rights process that allows the signature-free modules to run on the cDSP.)。Unsigned PD可以让一些低权程序运行在dsp上,主要还是被用于神经网络推理。但是就是这个Unsigned PD也是不是那么好用的,这里直接copy小米mace框架里面的so和代码,在执行任何dsp api之前调用hexnn_controller_request_unsigned_pd(//github.com/XiaoMi/mace/blob/fa72958a647be9457cf0a19d2f1195205a4b1a58/mace/runtimes/hexagon/dsp/hexagon_dsp_wrapper.cc) 。 这里不得不感叹一句,这些厂家的py关系真好。

  当所有部署完毕之后,执行dsp程序得到如下图结果:

rep_img

RK3588 NPU使用率查询


  要实现高通dsp使用率的查询,我们最开始查询到的一点资料是一个sysmon tools,这个工具在高通的sdk中,所以我们按照这个方向走下去。

rep_img

后记


  这里关于dsp编程来说,我这里可以说仅仅是一个小demo,这个部分最有价值的还是计算加速部分,一些重要的向量运算,这次我没有这个需求就不去关注了。

  但是换句话说,有了这一部分的经验后,后面哪怕是学习一些深入的东西,也是有一点基础在的。

参考文献

[1]Qualcomm.Hexagon SDK 3.5.4 Doc
[2]RockChip.Rockchip_RKNPU_User_Guide_RKNN_API_V1.3.0_CN


打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)
qrc_img

PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。

如某些图片无法查看,请尝试开启外网