用于Python的CPU Flame图

Cro*_*han 28 c python performance visualization linux-kernel

Brendan Gregg的CPU Flame Graph是一种基于调用堆栈在一段时间内可视化CPU使用情况的方法.

他的FlameGraph github项目提供了一种与语言无关的绘制这些图形的方法:

对于每种语言,FlameGraph都需要一种以如下行的形式提供堆栈输入的方法:

grandparent_func;parent_func;func 42
Run Code Online (Sandbox Code Playgroud)

这意味着检测程序被观察到运行函数func,其中parent_func调用它从顶级函数调用grandparent_func.它说调用堆栈被观察了42次.

如何从Python程序中收集堆栈信息并将其提供给FlameGraph?

对于奖励积分:如何扩展以便显示C和Python堆栈,甚至是Linux上的内核(与Brendan网站上的某些Java和node.js火焰图类似)?

在此输入图像描述

gdl*_*lmx 8

也许你可以试试sys.setprofile,这是标准的Python分析器核心profilecProfile.此方法为每个函数的"call"和"return"事件设置一个钩子,包括C-API的那些函数.

系统的配置文件函数的调用类似于系统的跟踪函数(请参阅settrace()),但不会为每个执行的代码行调用它(仅在调用和返回时调用,但即使异常已经报告,也会报告返回事件)组).

以下是一个工作示例:

from time import clock 
t0 = clock()

def getFun(frame):
    code = frame.f_code 
    return  code.co_name+' in '+code.co_filename+':'+str(code.co_firstlineno)

def trace_dispatch(frame, event, arg):
    if event in [ "c_call" , 'call', 'return', 'c_return']:
        t = int((clock()-t0)*1000)
        f = frame
        stack=[]
        while(f):
          stack.insert( 0,getFun(f) )
          f = f.f_back
        print event, '\t', '; '.join(stack), '; ', t

import sys
sys.setprofile(trace_dispatch)
try:
    execfile('test.py')
finally:
    sys.setprofile(None)
Run Code Online (Sandbox Code Playgroud)

Test.py

def f(x):
    return x+1
def main(x):
    return f(x)
main(10)
Run Code Online (Sandbox Code Playgroud)

这将打印出来

c_call    0
call      <module> in test.py:2 ;  1
call      <module> in test.py:2; main in test.py:5 ;  1
call      <module> in test.py:2; main in test.py:5; f in test.py:2 ;  5
return    <module> in test.py:2; main in test.py:5; f in test.py:2 ;  8
return    <module> in test.py:2; main in test.py:5 ;  11
return    <module> in test.py:2 ;  14
c_return  18
c_call    21
Run Code Online (Sandbox Code Playgroud)

在此处查看更全面的分析功能.

在python中的C堆栈

您无法访问python解释器中的C堆栈.必须使用支持C/C++的调试器或分析器.我建议使用gdb python.