论文: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)

Last modification:April 23rd, 2021 at 09:16 pm