RenderDoc 集成解读:使用 Lizard 库在 Android 设备上采集 ARM 硬件计数器

发布时间:2026/9/24 13:57:01
RenderDoc 集成解读:使用 Lizard 库在 Android 设备上采集 ARM 硬件计数器 开发工具调试器图形学GPU【免费下载链接】renderdocRenderDoc is a stand-alone graphics debugging tool.项目地址https://gitcode.com/gh_mirrors/re/renderdoc点击查看免费下载Lizard 是 RenderDoc 仓库中内置的一个开源库MIT 许可专门用于在 Android 设备上采集 ARM 硬件计数器其源码位于 renderdoc/driver/ihv/arm/official/lizard/ 目录。它既可以直接调用少量硬件计数器也可以通过 ARM Streamline 生态的gatord守护进程获取更完整的 Mali GPU/CPU 计数器集合。读完本文你将掌握 Lizard 的部署流程构建并推送gatord、以-M参数指定 Mali 设备型号启动、其 C/C 两套 API 的完整调用方式以及 RenderDoc 如何通过 arm_counters.cpp 把 Lizard 桥接为自身的性能计数器后端。Lizard 在 RenderDoc 中的定位Lizard 由 Samsung Electronics (UK) Limited 于 2020 年开发并开源其定位是在 Android 设备上捕获 ARM 硬件计数器的库原文Lizard is a library to capture ARM hardware counters on Android devices。在 RenderDoc 的项目结构中它位于 IHVIndependent Hardware Vendor独立硬件厂商集成层之下AMD 使用 GPUPerfAPI / RGP / AGSrenderdoc/driver/ihv/amd/Intel 使用 metrics discoveryrenderdoc/driver/ihv/intel/NVIDIA 使用 NVAPI / PerfSDK / Aftermathrenderdoc/driver/ihv/nv/ARM 则使用 Lizardrenderdoc/driver/ihv/arm/official/lizard/从构建配置 renderdoc/driver/ihv/arm/CMakeLists.txt 可以看到只有目标平台为ANDROID时Lizard 的源文件lizard.cpp、lizard_api.cpp、lizard_communication.cpp、hwcpipe_api.cpp、gator_api.cpp、socket.cpp以及 HWCPipe 及其 Mali/PMU vendor 实现才会被编译进rdoc_arm对象库非 Android 平台则回退到arm_counters_stub.cpp空实现。这印证了 Lizard 的 Android 专属属性。Lizard 的能力模型是一个双源计数器系统定义于 include/lizard/lizard_counter.hpp 的SourceType枚举计数器来源说明SOURCE_GATORD通过 gatord 守护进程ARM Streamline 的 gator 后端采集SOURCE_HWCPIPE_CPU通过 HWCPipe 的 PMU profiler 采集 CPU 计数器SOURCE_HWCPIPE_GPU通过 HWCPipe 的 Mali profiler 采集 GPU 计数器ClassTypeCLASS_ABSOLUTE/CLASS_DELTA描述计数器值是绝对值还是采样区间内的增量UnitTypeUNITS_BYTE、UNITS_CELSIUS、UNITS_HZ、UNITS_MHZ、UNITS_PAGES、UNITS_RPM、UNITS_S、UNITS_V、UNITS_MV、UNITS_UNKNOWN则描述数值单位。部署 gatordARM 硬件计数器的完整采集通道README 明确指出使用 gatord 这一步是可选的——Lizard 本身已经可以直接查询少量硬件计数器走 HWCPipe 通道。但如果想要获取更完整的计数器集合就需要部署 gatord。完整步骤如下。第 1 步为 Android 构建 gatordgatord是 ARM Streamline gator 采集体系中的设备端守护进程。需要先在 Android 工具链环境下完成其交叉编译得到 Android 可执行文件。第 2 步推送到设备可读/可写/可执行目录将gatord复制到 Android 设备上一个公开可读、可写且可执行的目录官方推荐使用/data/local/tmp该目录天然具备应用沙箱外的临时执行权限$ adb push gatord /data/local/tmp/gatord第 3 步以-M参数指定 Mali 设备型号并启动$ adb shell ./data/local/tmp/gatord -M G71其中-M参数用于指定 Mali 设备类型例如 G71、G76 等对应 Mali Midgard/Bifrost 系列 GPU 的型号代号。实际型号需要与设备内置的 Mali GPU 型号一致否则计数器枚举可能不完整或无法匹配。启动后 gatord 会监听网络端口等待 Lizard 客户端位于 Android 设备本机连接并协商计数器配置。从 gator_constants.hpp 可以看出 Lizard 与 gatord 之间是一套自定义的二进制协议包含帧类型FRAME_SUMMARY、FRAME_BACKTRACE、FRAME_COUNTER、FRAME_BLOCK_COUNTER、FRAME_PERF_ATTRS、FRAME_PERF等命令类型COMMAND_REQUEST_XML请求计数器 XML 定义、COMMAND_DELIVER_XML下发 XML、COMMAND_APC_START开始 APC 采集、COMMAND_APC_STOP停止采集、COMMAND_DISCONNECT、COMMAND_PING响应类型RESPONSE_XML、RESPONSE_APC_DATA、RESPONSE_ACK、RESPONSE_NAK、RESPONSE_ERROR。gatord_xml_reader.cppgatord_xml_reader.cpp负责解析 gatord 下发的计数器 XML 描述将其转换为 Lizard 内部统一的计数器描述结构。不经 gatord 的轻量通道HWCPipe 直采Lizard 内嵌了 HWCPipe其自身 README 位于 thirdparty/hwcpipe/README.mdHWCPipe 是一个读取 CPU 和 GPU 硬件计数器的简单可扩展接口支持自动平台检测构造hwcpipe::HWCPipe后自动识别 CPU/GPU 计数器集run()/sample()/stop()三阶段采集循环sample()按需返回Measurements结构体通过CpuCounter/GpuCounter枚举或 JSON 字符串如{cpu: [Cycles, Instructions], gpu: [GpuCycles]}选择计数器。在 Android 上使用 HWCPipe 通道时需要在设备上开启 profiling 权限某些设备默认是关闭的adb shell setprop security.perf_harden 0从 C 入口加载 Lizardlizard_api.h 详解Lizard 对外暴露的是一个纯 C 接口头文件为 include/lizard/lizard_api.h通过版本化结构体LizardApi组织全部函数指针当前版本为LIZARD_VERSION_0_1。加载方式如下头文件内附的官方示例void* lib dlopen(liblizard.so, RTLD_LAZY); LZD_LoadApi_PFN loadApi (LZD_LoadApi_PFN)dlsym(lib, LoadApi); struct LizardApi* api; if (loadApi(api) ! LZD_OK) { // report failure and return } if (api-version ! LIZARD_VERSION_0_1) { // report version mismatch and return } LizardInstance ctx api-Init(127.0.0.1, 8080);完整函数签名与语义如下函数签名作用InitLizardInstance (*)(const char *host, int port)初始化 Lizard 实例host/port为目标 gatord 的 IP 与端口Destroyvoid (*)(LizardInstance ctx)销毁实例并将指针置 NULLGetAvailableCountersCountuint32_t (*)(LizardInstance ctx)返回可用计数器数量ID 范围为[1, MAX_UINT]0 无效GetCounterDescriptionLZD_Result (*)(ctx, id, LizardCounterDescription*)填充计数器描述见下表EnableCountervoid (*)(ctx, id)启用某个计数器参与采集DisableCountervoid (*)(ctx, id)禁用某个计数器DisableAllCountersvoid (*)(ctx)禁用全部计数器默认状态下所有计数器均为禁用StartCaptureLZD_Result (*)(ctx)开始采集实际采集在独立线程执行StopCaptureLZD_Result (*)(ctx)停止采集ReadCounterIntint64_t (*)(ctx, id)以整型读取计数器测量值ReadCounterDoubledouble (*)(ctx, id)以双精度浮点读取计数器测量值LizardCounterDescription结构体携带计数器的完整元数据id、short_name、name、title、description、category、multiplier换算倍率、units单位、class_type绝对值/增量、result_typeLZD_TYPE_INT/LZD_TYPE_DOUBLE。典型采集流程为Init→GetAvailableCountersCountGetCounterDescription枚举 →EnableCounter选择目标计数器 →StartCapture→ 采样→StopCapture→ReadCounterInt/ReadCounterDouble读取结果 →Destroy。C 封装lizard.hpp 的使用模式C 层封装在 include/lizard/lizard.hpp 的lizard::Lizard类中内部组合了GatorApigatord 通信、HwcPipeApiHWCPipe 通信以及两个后台线程CommunicationThread/HwcPipeThread。核心成员bool configure(const char *hostname, uint32_t port)同时尝试配置 gatord 通道configureGatord与 HWCPipe 通道configureHwcPipe只要任一成功即返回 trueuint32_t availableCountersCount()/availableCounters(...)查询可用计数器列表void enableCounters(const LizardCounterId*, uint32_t)/disableCounters(...)按 ID 批量启用/禁用bool startCapture()非阻塞底层通信由独立线程完成内部先startGatord()重发计数器配置、启动会话、拉起通信线程再startHwcPipe()void endCapture()停止两个通道并回收线程readCounterInt/readCounterDouble/readCounter/getCounterInfo读取测量值与计数器元数据。实现细节lizard.cpp中值得注意的点采集前m_dataStore.clear()清空上一轮数据gatord 通道启动时会按已启用且sourceType() SOURCE_GATORD的计数器调用resendConfiguration随后startSession并创建CommunicationThread线程内持续接收 gatord 下发的 APC 计数数据HWCPipe 通道会按启用的 CPU/GPU 计数器调用m_HwcPipeApi-enableCounters(...)后启动HwcPipeThreadconfigureGatord期间会完成建连、版本协商sendVersion、计数器枚举init与断开sendDisconnect的完整握手即配置阶段是一次性的短连接。计数器数据结构与数据存储include/lizard/lizard_counter.hpp 定义了三个关键类型Valueint64_t与double的联合体统一承载两种类型的测量值LizardCounterData某个计数器在某次采集区间内的值序列getLength()个采样点可通过getIntValues()/getDoubleValues()按类型取用isInt()判断其类型LizardCounterDataStore以内部 key即计数器 ID为索引、值为向量序列的存储映射由后台线程持续写入、采集端批量读取。RenderDoc 侧集成ARMCounters 桥接层RenderDoc 通过 arm_counters.cpp 将 Lizard 封装为标准的ARMCounters计数器后端与 RenderDoc 的GPUCounter枚举体系打通。关键调用链ARMCounters::Init()LoadApi(m_Api)加载 Lizard API → 校验version LIZARD_VERSION_0_1→m_Api-Init(127.0.0.1, 8080)连接本机 gatord固定端口 8080因此 gatord 需监听该端口→GetAvailableCountersCount枚举若为 0 则失败返回枚举阶段对每个LizardCounterId调用GetCounterDescription再经ARMCreateCounterDescription映射为 RenderDoc 的CounterDescription——result_type映射为CompType::UInt/Floatunits映射为CounterUnit::Bytes/Celsius/Hertz/Seconds/Volt等计数器索引映射到GPUCounter::FirstARM idx采集生命周期BeginPass中逐个EnableCounterBeginSample(eventId)调用StartCaptureEndSample调用StopCapture后按计数器的resultType分别用ReadCounterInt/ReadCounterDouble取数并写入m_CounterData[eventId][counterId]GetCounterData将内部存储转成CounterResult(eventId, counter, value)列表返回给上层如性能计数器查看器。这意味着在 Android 上使用 RenderDoc 的性能计数器功能时用户只需先按本文部署并启动 gatordRenderDoc 的 ARM 后端会自动通过 127.0.0.1:8080 与之协作无需关心底层协议细节。部署与使用注意事项gatord 目录权限/data/local/tmp是官方推荐目录需保证公开可读、可写、可执行否则 gatord 无法启动或被 Android SELinux 策略拦截-M参数必须与设备的 Mali GPU 型号匹配如 G71、G76型号错误会导致计数器定义不匹配网络约束RenderDoc 侧默认以127.0.0.1:8080连接gatord 与 RenderDoc 必须运行在同一 Android 设备的本机回环上或自行修改端口约定HWCPipe 权限若不使用 gatord、走 HWCPipe 直采通道需先执行adb shell setprop security.perf_harden 0开启 profiling平台限定Lizard 仅在 Android 构建中生效桌面平台编译的是 arm_counters_stub.cpp 空实现这是构建配置 CMakeLists.txt 明确约束的。对想深入研究的读者建议依次阅读 lizard_api.hC 接口契约、lizard.cpp双通道调度逻辑、gator_constants.hppgatord 协议定义以及 arm_counters.cppRenderDoc 集成样例即可完整还原设备端采集 → 本机协议传输 → 上层展示的全链路。赞分享开发工具调试器图形学GPU【免费下载链接】renderdocRenderDoc is a stand-alone graphics debugging tool.项目地址https://gitcode.com/gh_mirrors/re/renderdoc点击查看免费下载相关推荐如何使用Flipper快速获取移动设备硬件参数开发者必备指南如何使用Flipper快速获取移动设备硬件参数开发者必备指南 Flipper是一款强大的移动开发者桌面调试平台能够帮助开发者轻松获取iOS和Android设开发工具调试器移动开发前端Renovate 的 ubuntu 版本策略解析 Ubuntu 容器镜像的语义版本号、代号与日期标签Renovate 的 ubuntu 版本策略解析 Ubuntu 容器镜像的语义版本号、代号与日期标签 本文围绕 Renovate 仓库中的 ubuntu 版本开发工具调试器图形学GPU上一篇Hyperledger Fabric 中的 multierrGo 多错误聚合库的能力演进与源码解析v0.1.0 → v1.11.0下一篇如何快速入门Grbl从Arduino烧录到基本G代码测试的10个步骤创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询