论文:Scalene: Scripting-Language Aware Profiling for Python
Github - plasma-umass/scalene
Scalene 是一个 Python 高性能 CPU, GPU 和内存分析器.
1. Scalene 特点
Scalene 具有快速且精确的特点,
[1] - Scalene 很快. 它使用采样的方式而不是直接测量或者依靠Python的追踪工具. 它的开销一般不超过10-20% (通常更少).
[2] - Scalene 精确. 和大部分其他的Python分析器不同,Scalene 在行级别下执行CPU分析,在程序中指出对应代码行的执行时间. 和大多数分析器所返回的函数级分析结果相比,这种程度的细节可能会更有用.
1.1. CPU 分析
[1] - Scalene 将在 Python 中和本地代码中花费的时间分开 (包括库). 大部分情况下并不会去优化本地代码 (通常是在 Python 实现中或者外部库), 所以这能有助于专注于实际上能够改进的代码.
[2] - Scalene 用红色 高亮热点 代码 (占用了大量 CPU 时间和内存分配的).
[3] - Scalene 还会分离出 系统时间, 使查找 I/O 瓶颈变得容易.
1.2. GPU 分析
[1] - Scalene 上报 GPU 时间 (目前仅限于基于nVidia的系统).
1.3. Memory 分析
[1] - Scalene 分析内存使用. 除了跟踪 CPU 使用, Scalene 也会指出需要为内存增长负责的特定代码行. 它是通过引用专门的内存分配器来实现的.
[2] - Scalene 分离出 Python代码 与 本地代码 内存消耗的百分比.
[3] - Scalene 产生 按行的内存分析.
[4] - Scalene 识别可能的内存泄漏.
[5] - Scalene 分析内存拷贝量, 从而易于发现意外的内存拷贝. 特别是因为跨越Python和底层库的边界导致的意外 (例如:意外的把 numpy
数组转化成了Python数组,反之亦然).
1.4. 其他特性
[1] - Scalene 可以生成 更少的分析 (通过 --reduced-profile
) 只上报那些超过 1% CPU 或者执行至少100个分配的代码行.
[2] - Scalene 支持通过 @profile
装饰器只对特定函数进行分析.
[3] - 当 Scalene 在对后台启动(通过 &
)的程序进行分析时, 可以 暂停和恢复分析.
2. Scalene 对比
2.1. 性能和特性
函数粒度的分析器 只上报整个函数的信息, 而 行粒度的分析器 (像 Scalene) 可以上报每一行的信息.
[1] - Time is either real (wall-clock time), CPU-only, or both.
[2] - Efficiency: (绿色)= 快, (黄色) = 较慢, (红色) = 最慢
[3] - Mem Cons.: 跟踪内存消耗
[4] - Unmodified Code: 适用于未修改的代码
[5] - Threads: 适用于线程
[6] - Python/C: 分别分析 Python/C 的时间和内存消耗
[7] - Mem Trend: 显示一段时间内的内存使用趋势
[8] - Copy Vol.: 上报内存拷贝量, 内存复制的 MB/s
2.2. 输出
Scalene 可以为正在被分析的程序打印带注释的源码 (通过 --html
选项打印文本或者HTML) 以及在同一目录下使用的任何模块 (可以选择 --profile-all
分析所有,也可以使用 --cpu-percent-threshold
,只分析 CPU 时间).
例如,代码片段 pystone.py
.
[1] - Memory usage at the top: 通过 "sparklines" 可视化, 分析的代码在运行期间的内存占用. Scalene 是一个统计的分析器, 意味着它使用采样,所以就肯定会有差异发生. 一个运行时间更长的程序可以分配和释放更多的内存,会获得更稳定的结果.
[2] - "CPU % Python": Python 代码占用的时间.
[3] - "CPU % Native": 本地代码占用的时间 (例如 C/C++ 写的库).
[4] - "Mem % Python": 相对于非 Python 代码(例如 C/C++ 写的库),Python 代码的内存分配.
[5] - "Net (MB)": 正数代表内存分配的净值,负数代表内存回收的净值.
[6] - "Memory usage over time / %": 通过 "sparklines" 可视化, 表示这些代码行在程序运行时产生的内存消耗,以及此行内存活动总的百分比.
[7] - "Copy (MB/s)": 复制的 MB/s (参见 "关于 Scalene").
3. Scalene 使用
Scalene 安装:
pip install scalene
3.1. 使用示例
Scalene 执行要分析的示例程序,命令行模式,如:
scalene demo.py
scalene [options] demo.py
python3 -m scalene [options] demo.py
3.2. scalene 参数
scalene --help
如:
scalene [-h]
[--outfile OUTFILE] [--html] [--reduced-profile]
[--profile-interval PROFILE_INTERVAL] [--cpu-only]
[--profile-all] [--profile-only PROFILE_ONLY]
[--use-virtual-time]
[--cpu-percent-threshold CPU_PERCENT_THRESHOLD]
[--cpu-sampling-rate CPU_SAMPLING_RATE]
[--malloc-threshold MALLOC_THRESHOLD]
参数说明,如:
[1] - --outfile
OUTFILE - 分析输出文件(default: stdout)
[2] - --html
- HTML 作为输出(default: text)
[3] - --reduced-profile
- 生成缩减版分析器,仅输出非零行(default: False)
[4] - --profile-interval
PROFILE_INTERVAL - 多少秒输出结果(default: inf)
[5] - --cpu-only
- 仅检测 CPU时间(default: profile CPU, memory, and copying)
[6] - --profile-all
- 对所有执行代码分析,而不仅是目标代码(default: only the target program)
[7] - --profile-only
PROFILE_ONLY - 仅对文件中包含给定字符串的代码分析(default: no restrictions)
[8] - --use-virtual-time
- 仅分析 CPU 时间,而不包括在 I/O或者 blocking 上的耗时(default: False)
[9] - --cpu-percent-threshold
CPU_PERCENT_THRESHOLD - 仅报告CPU 时间超过指定比例的分析(default: 1%)
[10] - --cpu-sampling-rate
CPU_SAMPLING_RATE - CPU 采样率(default: every 0.01s)
[11] - --malloc-threshold
MALLOC_THRESHOLD - 仅报告至少要分配(allocations)的次数(default: 100)