Go怎么做性能优化工具篇之 trace工具

embedded/2024/12/27 16:29:58/

一、什么是 trace

trace 是 Go 语言的一个非常强大的性能分析工具,它用于追踪和记录 Go 程序的执行过程。与 CPU 和内存性能分析工具(如 pprof)不同,trace 侧重于在时间维度上分析程序的行为,帮助开发者理解程序执行中的时间分布、并发和调度等方面的细节。

二、如何使用 Go Trace

1、启用 trace

Go Trace 的启用非常简单。你只需要在程序中插入 runtime/trace 包,并在合适的地方启动和停止 trace。具体步骤如下:

package mainimport ("fmt""runtime/trace""os""time"
)func main() {// 创建一个文件来保存 trace 信息f, err := os.Create("trace.out")if err != nil {fmt.Println("could not create trace file:", err)return}// 启动 tracedefer f.Close()if err := trace.Start(f); err != nil {fmt.Println("could not start trace:", err)return}// 确保在函数退出时停止 tracedefer trace.Stop()// 模拟程序执行的任务simulateTask()
}func simulateTask() {// 模拟一段时间的工作fmt.Println("Task started")time.Sleep(2 * time.Second)fmt.Println("Task completed")
}

执行上述脚本后,会生成一个 trace.out 文件

2、分析trace文件

生成 trace 文件后,使用 go tool trace 命令来分析该文件。该命令会启动一个 web 界面,帮助你查看程序的详细执行过程。

go tool trace trace.out

执行该命令后,会启动一个本地的 Web 服务器
在这里插入图片描述
跳转打开之后
在这里插入图片描述
点击协程分析:
在这里插入图片描述
可以看到协程运行时间、同步阻塞时间、系统调用阻塞时间、调度延迟时间等。
如果发现某个数据不正常,可以点击看上面的链接,就可以定位到具体的阻塞代码了

当我们想要查看处理器的使用状况时,便可以使用处理器分析视图(View trace by Proc)。后面就是这个视图的样子。
在这里插入图片描述
借助处理器视图,我们可以了解到多核是否处于被充分使用,也能够知晓在某一特定时刻,处于不同状态的协程数量分别是多少。如果处于可调度(Runnable)状态的协程数量较多,可能意味着创建的协程数量过多,导致无法得到 CPU 的有效调度。而且我们还能够查看在那些占用处理器时间的各类事件当中,究竟哪些是由垃圾回收(GC)所占用的。倘若垃圾回收占用 CPU 的时间过多,这同样也意味着程序处于一种不健康的运行状态

以下是各个链接的说明:

2.1 View trace(常用)

是指查看完整的 trace 文件,观察程序的执行路径和执行过程,通常会包括以下信息:Goroutine 的生命周期、各种事件(如内存分配、垃圾回收)、调度、等待、阻塞等状态、Trace 数据通常通过 runtime/trace 包生成并保存为 .out 文件,之后通过 go tool trace 命令进行查看。

2.2 Goroutine analysis(常用)

这一部分显示了所有 Goroutine 的活动和状态。Go 的并发模型是基于 Goroutines(轻量级线程)实现的,而通过 Goroutine 分析,你可以:看到每个 Goroutine 执行的任务、分析 Goroutine 是否在阻塞、等待或过度创建等情况、观察 Goroutine 的调度、启动和终止等

2.3 Network blocking profile

这一部分分析网络相关的阻塞情况,通常是程序在进行网络操作时(例如 HTTP 请求、数据库连接等)发生的阻塞。它显示了因为网络操作而导致的延迟或卡住的情况。具体来说,可能的网络阻塞包括:

  • 网络请求的等待时间(如 DNS 查询、HTTP 请求等待等)
  • 网络连接建立和关闭的阻塞
  • 数据传输时的等待
    这种阻塞通常会影响应用程序的响应性和性能,因此网络阻塞分析对于优化程序的网络操作至关重要。
2.4 Synchronization blocking profile

Synchronization blocking profile 分析了程序中由于同步操作(如锁、信号量、条件变量等)而发生的阻塞情况。这类同步操作通常是为了保护共享资源,防止数据竞态问题。阻塞通常发生在以下场景:
竞争条件:多个 Goroutine 同时请求获取同一资源(例如,通过互斥锁 mutex)。
等待某些条件的发生(例如条件变量 Cond 的等待)。如果程序过度使用同步原语(例如 sync.Mutex 或 sync.WaitGroup),或者同步操作设计不当,可能会导致性能瓶颈。通过这部分分析,你可以了解在哪些同步点程序被阻塞,并优化同步的粒度和设计。

2.5 Syscall blocking profile

Syscall blocking profile 分析了程序在进行系统调用(如文件操作、网络 I/O、内存管理等)时发生的阻塞情况。Go 程序的系统调用通常是同步的,这意味着程序在等待 I/O 操作完成时会被阻塞。常见的系统调用包括:

  • 网络 I/O 操作(如 net.Dial、http.Get 等)
  • 文件 I/O 操作(如读写文件)
    操作系统的其他资源访问(如进程创建、内存分配等)
    如果应用程序的性能瓶颈出现在系统调用上,可能需要考虑优化 I/O 操作,减少阻塞的时间,或使用异步 I/O 模型。
2.6 Scheduler latency profile

Scheduler latency profile 分析了 Go 程序中调度器的延迟问题。Go 语言的调度器负责将 Goroutine 映射到操作系统线程,调度延迟可能会影响程序的响应时间和吞吐量。常见的调度延迟问题包括:

  • Goroutine 长时间没有被调度执行
  • 某些 Goroutine 被延迟调度,导致响应时间增加
  • 调度器的上下文切换过于频繁,影响程序性能

通过这一部分的分析,开发者可以确定是否存在调度瓶颈,并相应地优化 Goroutine 的调度策略,例如调整 Goroutine 的优先级、减少不必要的上下文切换等。

2.7 User-defined tasks

User-defined tasks 是程序员通过 runtime/trace 的 WithRegion 和 Eventf 等接口定义的自定义任务。Go 的 Trace 工具允许开发者手动标记特定的任务或操作,以便后续分析。例如,你可能会将某个重要的业务逻辑部分(如数据库查询、复杂计算等)标记为任务,并查看它的执行情况和性能。
用户定义任务 对于标记和分析关键代码路径非常有用,帮助开发者聚焦于特定部分的性能瓶颈。

2.8 User-defined regions

User-defined regions 是程序员自定义的代码区域,通常用 WithRegion 函数来标记。类似于自定义任务,区域是对程序执行的特定代码块进行的标记,用于分析该区域的执行时长和性能。例如,你可以在一个数据库查询操作的开始和结束处插入 WithRegion,以查看该查询所占用的时间。

用户定义区域 让开发者能够细粒度地分析程序的执行,并且将重点放在程序中耗时较长的区域上。

2.9 Minimum mutator utilization

Minimum mutator utilization 是 Go 程序中与垃圾回收(GC)相关的一个度量,表示在 GC 运行期间,程序的“变异器”(Mutator)部分的工作效率。变异器是指执行用户代码的部分,它在 GC 期间可能会被暂停或延迟。如果变异器的利用率较低,意味着 GC 占用了太多的 CPU 时间,导致应用程序性能下降。

Mutator:指执行用户代码的 Goroutine,它在垃圾回收的过程中会被暂停。
利用率:表示在 GC 期间,变异器代码的执行时间相对于 GC 停顿时间的比例。
最低变异器利用率 是评估垃圾回收效率和程序性能的一个指标。如果该值过低,说明 GC 的停顿时间过长,可能需要优化内存管理或减少垃圾回收的频率。

三、Go的性能优化代码实践(下篇)


http://www.ppmy.cn/embedded/149212.html

相关文章

【Redis】 数据淘汰策略

面试官询问缓存过多而内存有限时内存被占满的处理办法,引出 Redis 数据淘汰策略。 数据淘汰策略与数据过期策略不同, 过期策略针对设置过期时间的 key 删除, 淘汰策略是在内存不够时按规则删除内存数据。 八种数据淘汰策略介绍 no evision&…

NIPS2014 | GAN: 生成对抗网络

Generative Adversarial Nets 摘要-Abstract引言-Introduction相关工作-Related Work对抗网络-Adversarial Nets理论结果-Theoretical Results实验-Experiments优势和不足-Advantages and disadvantages缺点优点 结论及未来工作-Conclusions and future work研究总结未来研究方…

自动驾驶控制算法-横向控制与流程代码仿真

本文是学习自动驾驶控制算法第八讲(一)横向控制算法与流程图以及后续两节的学习笔记。 1 1. 算法流程图 2 A,B计算模块 A [ 0 1 0 0 0 C α f C α r m v x − C α f C α r m a C α f − b C α r m v x 0 0 0 1 0 a C α f − b C α r I v x −…

ElasticPDF-新国产 PDF 编辑器开发框架(基于 pdf.js Web PDF批注开发,实现高亮多边形橡皮擦历史记录保存注释文字)

摘要: ElasticPDF 是一款新国产 PDF 编辑器开发框架,基于开源 pdf.js 的渲染框架,增加了批注功能,支持全离线运行,适用于公网及内网系统。代码包结构延续了 pdf.js-dist 简洁的风格,兼容所有主流浏览器&…

HTMLCSS:超炫丝滑的卡片水波纹效果

这段代码创建了一个卡片,卡片上有三个波动效果,这些波动效果通过 CSS 的keyframes 动画实现,创建了一个旋转的动画效果。这种效果适用于创建动态的视觉效果,例如音乐播放器的封面、动态背景或其他需要动态效果的界面元素。 演示效…

【优选算法---归并排序衍生题目】剑指offer51---数组中的逆序对、计算右侧小于当前元素的个数、翻转对

一、剑指offer51---数组中的逆序对 题目链接: LCR 170. 交易逆序对的总数 - 力扣(LeetCode) 题目介绍: 在数组中的两个数字,如果前面⼀个数字大于后面的数字,则这两个数字组成⼀个逆序对。输入一个数组&#xff0c…

Linux复习4——shell与文本处理

认识vim编辑器 #基本语法格式: vim 文件名 •如果文件存在,进入编辑状态对其进行编辑 •如果文件不存在,创建文件并进入编辑状态 例: [rootlocalhosttest]# vim practice.txt #Vim 编辑器三种模式: 命令模式&a…

stm32能跑人工智能么

STM32确实能够运行人工智能算法,这得益于其强大的计算能力和丰富的外设接口,为运行小型人工智能算法提供了基础。以下是对STM32运行人工智能能力的详细分析: 一、硬件基础 STM32作为一款广泛应用于工业控制、智能家居等领域的微控制器&…