MegEngine 使用小技巧:Profiler 使用手册

【Android】Profiler使用 最近在做地图相关业务的时候,发现进入导航的一瞬间系统特别卡,当时就是用的profiler工具分析出来是因为高德的SDK在进入导航的时候短时间内创建了大量的对象引起内存抖动。这次主要简单介绍Profiler关于分析内存的简单使用,可以分析内存泄漏或者观察应用以及引用的SDK创建了多少对象。下面是上图每个数字对应的简单的介绍选择【MEMORY】进行内存分析记录系统内存变化,可分析是否有内存泄漏一段时间内C/C++的对象的使用数量一段时间内Java/kotlin对象的使用数量开始/暂停。 阅读详情

0.写在前面

“xx,R 那边反应多机训练速度慢,你看一下什么情况”

“xxx,为什么 MGE 更新之后,xxx 网络训练变慢了,你看一下”

这是组内日常对话

然后有人日常背锅

组员的状态是:提性能,提性能,还是 TMD 提性能

据不完全统计,有 80% 的性能问题其实是因为训练代码写的不够好,让 MGE 有力使不出来

包括但不限于以下情况

1)没开 fast_run

2)频繁使用 numpy 进行同步

3)没有用 make_allreduce_cb,让计算通信串行

4)。。。

次数多了,就发现这玩意太花时间了,而且每次的步骤都千篇一律,为啥一定要我来做,所以写这篇文章进行总结,方便大家也方便自己

1.Profiler 介绍

首先我们要认识 Profiler 这个东西

简单来说,Profiler 以时间轴的形式记录了所有算子的运行时间

通过 Profile 结果,我们可以很快的发现这段代码为什么跑的慢

是做了多余的工作?还是计算资源的浪费?或者是算子本身的性能很差,需要替换成别的算子

1.png

这是一个简单的 profile 结果展示

大部分情况下我们只关注 gpu thread,每一个 gpu thread 对应一个 cuda stream,上面都是运行在这个 cuda stream 上的算子

2.使用方式

PS:静态图的统计信息还不够完善(受到图优化影响),profile 结果相对动态图的不够友好

from megengine.utils.profiler import profile, Profiler
 
# 装饰器写法
@profile()
def train_step(data, label, *, optimizer, gm, model)
    with gm:
        logits = model(data)
        loss = F.loss.cross_entropy(logits, label)
        gm.backward(loss)
        optimizer.step().clear_grad()
    return loss
 
# with 写法
# 训练过程中最好只有一个profiler实例,因为profiler会在析构时自动dump出结果,如果有多个实例的话每个iter都会dump,非常慢
profiler = Profiler()
 
def train_step(data, label, *, optimizer, gm, model)
    with profiler:
       with gm:
           logits = model(data)
           loss = F.loss.cross_entropy(logits, label)
           gm.backward(loss)
           optimizer.step().clear_grad()
    return loss

⚠️注意,profiler 默认会在析构的时候导出 profile 结果,也可以手动调用 profiler.dump 方法手动 dump

参数说明:

Profiler 的构造函数支持如下参数:

  • path:  profile 数据的存储路径,默认为当前路径下的 profile 文件夹.
  • format: 输出数据的格式,默认为 chrome_timeline.json ,是 Chrome 支持的一种标准格式,以时间线的形式展现 profiling 结果. 可选项还有 有 memory_flow.svg ,以时间x地址空间的形式展示内存使用情况.
  • formats:  若需要的输出格式不止一种,可以在 formats 参数里列出.
  • sample_rate:  若该项不为零,则每隔 n 个 op 会统计一次显存信息,分析数据时可以绘制显存占用曲线,默认为 0.
  • profile_device:  是否记录 gpu 耗时,默认为 True.
  • with_scopes:  是否额外记录 functional/ tensor method 等 python API 对应的 scope, 默认为 False.
  • with_backtrace: 是否记录 op/event 对应的 python 调用栈, 默认为 False, 开启会使记录数据文件体积变大.

scope 使用介绍

我们会自动在 module 的 forward 还有 backward 以及 step 步骤中加入 scope,scope 会在 host thread 上显示,能看出 op 属于哪一个 module 的什么阶段

2.png

也可以自己加上 scope

from megengine.utils.profiler import Profiler, scope
 
def main()
    with Profiler():
        x = Tensor(1)
        with scope("Add"):
            y = x+1
        with scope("Mul"):
            z = x*3

默认情况下 profiler 只会记录 module forward, backward, step 三类 scope, 用户可以在构造 Profiler 对象时传入参数 with_scopes = True 额外记录 functionaltensor methodapi 调用对应的 scope

开启 with_scopes 选项后额外记录了 BatchNorm2d Module 内部调用的 functional / tensor method API 调用 scope

3.png
开启 with_scopes 选项后额外记录了 backward scope, 该 scope 用于记录反向计算序列对应的前向算子, 可用于查找反向计算中有性能问题的算子是由哪种算子前向计算产生。下图 scope 表示 Broadcast, SetSubtensor 等算子是由 Subtensor 反向计算产生的。

4.png

3.可视化显示

推荐使用 perfetto 查看 profile 结果,也可以用 Chrome 开发者模式(F12)的 Performance 模块查看 timeline 格式文件,也可以用 chrome://tracing/ 进行查看

以下介绍的都是基于 perfetto 的操作方式

1)统计

可以选中一段连续的时间段,查看这一个时间段的统计结果

下方会显示事件统计结果,可以看到事件实际占用时间(Wall duration)(可以结合总时间算出空闲时间),可以按照总占用时间排序,也可以按照平均时间排序

5.png

2)依赖关系

在 host thread上,op 会记录对应的 input和output 以及相应的依赖关系,可以依据箭头找到 input 依赖的上一个 op,也可以通过下方 flow event 点击移动到上一个或者下一个

6.png

7.png

我们还能找到 op 对应的 host 时间和 gpu 时间,点击 op 可以看到在不同 thread(cpu,gpu)占用的时间

8.png

3)查看显存使用, gpu 利用率等指标

profiler 除了记录时间算子执行时间外,还会记录一些与显存和性能相关的指标。gpu_usage_ratio 记录程序执行平均的 gpu 利用率(gpu 执行 kernel 时间占总时间的比例),gpu_usage_ratio 低说明程序 host 侧是瓶颈 。gpux:x alloc_mem_value 记录了gpux 显存使用量随时间的变化的曲线, 需要把 sample_rate 设置为大于 0 的整数(sampe rate 代表每隔 n 个 op 记录一次显存使用量)

9.png

4)放大缩小

可以拖动上方时间轴的起始和结束点来修改起始点和结束点,也可以通过放大缩小手势进行放大缩小

中间竖线上面的灰色小方块就是可以拖动的点

10.png
11.png

4.常见调试技巧(附使用例子

1)多余计算

12.png
yolox 例子,forward,backward,step 运行完成了,但是后面多出了很多的 reshape 操作(一般认为 reshape 无实际计算,所以基本看作是浪费

找到原因后结果如下(5s->1.3s)

13.png

2)计算通信串行(请认准 make_allreduce_cb)

allreduce 通信在 gpu0:1,如果发现通信在 gpu0:0 那就是用错了

14.png

3)host 性能慢,gpu 利用率不高

15.png

cpu 时间和 gpu 时间基本上一致,很可疑

放大仔细看,gpu 运行时间中有很多空隙,而且点击对应 op 查看依赖关系,可以看出中间的空隙时间是在等待 host 进行 launch cuda kernel

16.png

4)使用  backtrace 记录功能查找性能瓶颈部分对应源码

上述示例介绍了如何从 profile 结果中发现性能异常的部分, profiler 提供了 backtrace 调用栈记录功能, 方便用户找到异常部分对应的训练代码源码。backtrace 记录会记录算子的 dispatch/kernel 执行,TensorWaitProperty 等事件对应的 python 调用栈。

可以在构造 Profiler 对象时通过传入 with_backtrace = True 开启调用栈记录功能。 开启该选项后 profiler 保存数据文件体积会增大。

用户可以在 perfetto UI 界面上点击 op 查看其对应的源码。

下图 profiler 结果中 CompiledOp[IOU] 算子执行时间较长, 通过记录的 backtrace 可以发现该算子是检测模型计算 loss 部分调用的。

17.png

下图中 interpreter 线程中某个 TensorWaitProp 占用时间很长,可能会拖慢 host 执行速度,导致 gpu 空闲。

(TensorWaitProp 可能是由 tensor.shape, tensor.numpy() 等方法调用产生的, 会让 host 侧等待 device 执行,以获取 Tensor 的 value 或 shape 属性)

通过调用栈可以发现该事件是由 basedet 检测模型 get_ground_truth 方法中的某个 getitem 产生的 ( __getitem__中使用了 tensor shape 属性触发了 host 侧的 sync)。
18.png

更多 MegEngine 信息获取,您可以:查看文档和 GitHub 项目,或加入 MegEngine 用户交流 QQ 群:1029741705。欢迎参与 MegEngine 社区贡献,成为 Awesome MegEngineer,荣誉证书、定制礼品享不停。

【游戏开发】常用Profiler使用总结 这篇文章总结一下在游戏开发过程中常用的几种Profiler使用,偏美术侧。 阅读详情

相关推荐

profiler

Profiler 是一种性能分析工具,在多个领域有着广泛的应用。在 SQL Server 中,SQL Profiler 是一个图形界面和一组系统存储过程。它可以用于监视 SQL Server 查询、收集查询信息、分析性能、诊断问题如死锁等,还能模拟重放 SQL Server 活动。启动 SQL Profiler 可以从开始菜单的“所有程序”中找到“Microsoft SQL Server 2008”下的“性能工具”打开,也可以在 SQL Server Management Studio 的“工具”中找到。

百态·数智思维 | 聚焦大数据、量化与未来AI 1024

AndroidStudio3.0 Android Profiler分析器(cpu memory network 分析器)

Android Profiler分为三大模块: cpu、内存 、网络。基本的使用在上一篇文章有讲到。这里详细说一下。cpu分析器CPU ProfilerCPU分析器可帮助您实时检查应用程序的CPU使用情况和线程活动,并记录方法跟踪,以便您可以优化和调试应用程序的代码。要打开CPU Profiler,请按照下列步骤操作: 点击 View > Tool Windows > Android Profile

KeepStudy 10万+

profiling 与性能优化总结

我们发现,主线程大约有80%的时间花在了等待上,如上图中的红色框所示。其中user和system的含义是user CPU time和system CPU time, 之所以会把CPU的执行时间分为两个部分,是因为程序在运行时除了执行程序本身代码和一些库的代码,还会调用操作系统提供的函数(即系统调用,程序运行系统调用时有更高的权限),因此程序运行时通常会处于两种状态: 用户态和内核态: 内核态指的是CPU在运行系统调用时的状态,而用户态就是CPU运行非系统调用(即用户自己的代码或一些库)时的状态。

m0_74282605的博客 1227

Android Profiler 内存分析器使用

Android Profiler 工具可提供实时数据,帮助您了解应用的 CPU、内存、网络和电池资源使用情况。

特立独行的博客 4800

MegEngine 7-8 双月报来啦:新版本发布,开发者福利课程,干货满满

MegEngine Python 层模块串讲(上)MegEngine Python 层模块串讲(中)MegEngine Python 层模块串讲(下)如有催更或投稿,欢迎联系我们哦~技术交流 QQ 群:1029741705;Bot 微信:megengine-bot。

MegEngine_Bot的博客 123

Python 和 C/C++ 拓展程序的性能优化

背景在 MegEngine imperative runtime 的早期开发中,我们面临着一些的性能优化问题。除了一些已知需要重构的地方(早期设计时为了开发效率而牺牲性能的妥协),还存在一...

Paper weekly 478

Android开发之——性能剖析器Profiler,赶紧学起来

(img-yxaxFt08-1711631583186)](img-cpeysdEB-1711631583186)]确保性能分析器当前未在 Android Studio 中运行。话不多说,Android实战系列集合都已经系统分类好,运行到设备后,点击Profiler,显示性能分析。三 将app运行后使用Profiler分析。转到安装目录,然后转到。合都已经系统分类好,

m0_60721649的博客 1623

Android开发之——性能剖析器Profiler

Profiler是什么 Android Studio 3.0 及更高版本中的 Android Profiler 取代了 Android Monitor 工具 Android Profiler 工具可提供实时数据,帮助您了解应用的 CPU、内存、网络和电池资源使用情况 二 如何打开Android Profiler 2.1 使用Android Studio开发工具时 依次选择: View > Tool Windows > Profiler 点击工具栏中的Profile 图标 2.2

我的博客 2106

JProfiler的安装和使用

JProfiler是一个重量级的JVM监控工具,提供对JVM精确监控,其中堆遍历、CPU剖析、线程剖析看成定位当前系统瓶颈的得力工具。可以统计压测过程中JVM的监控数据,定位性能问题。 JProfiler下载与安装 环境准备 JProfiler 17.1.5(IDEA插件) JProfiler 9.2(可执行软件) IntelliJ IDEA 2017.2.5 JProfiler插件安装 方式...

vicky_pyh的博客 3万+

性能评估工具Profiler使用与相关介绍

在这个界面中就可以对模型的各项运行性能进行一个详细的观测:在上面的界面中有GPU Sunmmary面板,这个面板中包含了GPU的基本信息、算力与使用率以及使用效率,右上角则为各种设备的使用时间与使用率。在小批次推理过程中,量化前后的网络模型体现并不明显,主要运行时间集中在CPU的计算过程中,这个过程主要是CPU对数据传输的过程,想要加速这个过程需要对CPU的使用做一定的处理。上述内容中需要注意的是这里的safetensor格式内容是通过量化后得到的,所以需要对模型的权重进行手动映射。

qq_41878154的博客 1480

Android开发之——性能剖析器Profiler,一文详解

分享一份NDK基础开发资料分享内容包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!资料的时间来学习,也可以分享动态给身边好友一起学习!

rt3Dmax9的博客 2089

性能优化第一步:Profiler使用

CPU Profiler 首先来说,CPU Profiler并不是专门用于处理页面卡顿掉帧的,准确说:CPU Profiler是用来查看每个线程,在某段一段时间内执行了哪些函数,以及在其执行期间每个函数消耗的 CPU 资源。 专门针对卡顿掉帧问题可以使用内置的小工具:systrace。 不整官网那么多“花里胡哨”的介绍,咱们直击上应用方式。 1、使用界面 点击启动后,我们就可以看到...

weixin_45365889的博客 1882

时间监控--Profiler使用方法

时间监控--Profiler使用方法 一、 概述 Profiler是一个时间统计程序,他通过在程序中埋点,将埋点时间记录入线程变量中以实现革离,最后dump出结果,得出埋点时间树。 二、 Profiler常用方法(Profiler类的静态方法)  1、Start 当前线程埋点计时的开始,标识当前埋点的开始时间,每个埋点产生一个Entry,被压入线程变量中的栈中,当sta

hualusiyu的专栏 1179

Android开发之——Profiler-网络分析

val httpAsync = “https://httpbin.org/get”.httpGet().responseString { request, response, result ->print(response)}httpAsync.join()val httpAsync = “https://www.wanandroid.com/banner/json”.httpGet().responseString { request, response, result ->print(response)

2401_83601703的博客 1297

Profiler使用

Profiler是一个分析app性能的强大工具合辑,可以分析内存、cpu、启动时间、网络情况、功耗等各个指标 cpu使用率 内存占用 网络流量监控 耗电量监控 CPU Profiler 可以让我们查看应用进程中的每个线程,某段时间内执行了哪些函数,以及在其执行期间每个函数占用CPU的时间 还可以使用函数跟踪来识别调用方和被调用方。 据此可以确定哪些函数负责调用常常会消耗大量特定资源的任务,并尝试优化应用代码以避免不必要的开支 JVM CPU Profiler技术原理及源码深度解析 https://www.c

weixin_42547039的博客 2755

使用 Android Studio Profiler 工具解析应用的内存和 CPU 使用数据

为了帮助开发者开发出更加轻快高效的应用,我们在 Android Studio 3.0 以及更高版本中加入了 Android Profiler 工具,用于应用的 CPU、内存、网络和能耗分...

谷歌开发者 3739

Unity性能优化(一)优化概述与Profiler工具的使用

最近在学习性能优化的内容,想写博客总结一下,这是我第一次写,所以可能会比较粗糙,后面会随着学习的深入不断完善学习性能优化之前你需要先知道什么是渲染管线,以及3D模型的基本知识,本文不给出相关教学性能优化的主要目的就是提高游戏帧数,而提高游戏帧数可以从优化代码,降低DrawCall等方面入手,在Game窗口点击Stats可以查看DrawCall、帧数、顶点数量、三角形数量、SetPass等信息,这些都是我们要重点关注的数据,Batches是DrawCall进行批处理以后的值,你可以理解为DrawCall。

qq_54476817的博客 1991
上一篇: 开源项目分享,实习宝典传授,直播课程报名开启!
下一篇: MegEngine 7-8 双月报来啦:新版本发布,开发者福利课程,干货满满
MegEngine_Bot
博客等级 码龄3年 169粉丝 · 19原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值