共计 858 个字符,预计需要花费 3 分钟才能阅读完成。
在一个网络编程性能优化我的项目中,利用 perf trace 进行性能剖析。
背景:一个过程负责解决 socket 音讯,在须要解决音讯数量达到 32k 条 100+ 字节的音讯量时,耗时大略须要 25 分钟
指标:定位耗时的热区
环境:linux
假如 1:用户态耗时多,过程耗时多是耗费在算法计算上?
该过程只进行简略的音讯解决,不波及过多数据结构和算法,排除该可能性。
假如 2:零碎态耗时多,过程耗时多是耗费在零碎调用上?
因为音讯量大,进行了 32k*n 数量级的零碎调用,假如有可能成立。
在这里,抉择应用 linux 的 perf 工具进行统计分析:
perf trace -p $PID -s
由上图可见,在解决一条音讯的过程中,大抵流程波及到与 socket 相干的 poll->recvfrom->sendto,同时还有与文件 IO 相干的零碎调用。解决 32k 条音讯,波及到的零碎调用数量在数量级上合乎预期。
- 指标统计分析:
fsync(), 该零碎调用用时最多,耗费了大略 15 分钟。该零碎调用用于同步写入磁盘,调用后会阻塞,直至期待内核缓冲区数据写入磁盘后,内核才会返回。定位到该零碎调用位于过程的日志模块。 - 针对该零碎调用改善:
业务数据日志,升高其日志等级,在运行过程时通过日志等级开发将对应的等级敞开,缩小日志输入;同时在日志模块中删除 fsync()调用,该类日志不须要实时同步至磁盘。
从新执行雷同的测试,过程总用时大概 50s。从本次检测到的零碎调用指标来看,解决了 fsync()带来了极大的晋升空间。
在这个实际中,能够看到 perf trace 的一个用途:统计肯定工夫内的零碎调用的次数以及其耗时散布。
思考 1:perf trace 统计的零碎调用,各列中的工夫是零碎工夫还是时钟工夫?集体认为是时钟工夫,因为只管是零碎调用,内核态也会处于一种阻塞状态,该状态不耗费 CPU 资源。例如过程调用 fsync(),陷入内核态,DMA 把零碎缓冲区的数据同步至磁盘,此过程过程睡眠,没有占用 CPU 资源,同步至磁盘实现后,DMA 会中断,CPU 进行响应解决,此时 fsync()调用完结,返回用户态。