支持 JIT 的分析器¶
目标:拥有一个了解 PyPy JIT 的分析器,并显示在哪些循环中花费了多少时间。
长期目标:将分析器收集的数据与 jitviewer 集成。
想法是在每次进入和退出循环或桥接时在 PYPYLOG 中记录一个事件。
预期输出¶
[100] {jit-profile-enter loop1 # 例如一个入口桥接 [101] jit-profile-enter} … [200] {jit-profile-enter loop0 # 从 loop1 跳转到 loop0 [201] jit-profile-enter} … [500] {jit-profile-exit loop0 # 例如由于保护失败 [501] jit-profile-exit}
在这个例子中,从 loop1 退出是隐式的,因为我们正在进入 loop0。因此,我们在入口桥接中花费了 200-100=100 个刻度,在实际循环中花费了 500-200=300 个刻度。
如何处理“内部”桥接?¶
“内部桥接”是指那些跳转回其源循环的桥接。有两种处理它们的方法:
- 我们忽略它们:我们记录何时进入循环,但不记录何时跳转到已编译的内部桥接。退出事件仅在非编译保护失败或跳转到另一个循环的情况下记录。
- 我们记录每个内部桥接的进入/退出。
解决方案 (2) 的缺点是,某些循环在每次迭代时都会使用桥接。因此,在这种情况下,我们将记录大量事件,可能会增加大量开销,从而使分析数据变得毫无用处。
检测进入/退出循环¶
进入方式
- 在跟踪/编译之后
- 从解释器,如果循环已经编译
- 从另一个循环,通过 JUMP 操作
- 从热保护失败(如果我们选择上面的解决方案 (1),我们将忽略它)
- XXX:我是否遗漏了什么?
退出方式
- 保护失败(进入黑洞)
- 保护失败(跳转到桥接)(如果选择解决方案 (1),则忽略)
- 跳转到另一个循环
- XXX:我是否遗漏了什么?
关于 call_assembler:我认为一开始,我们应该忽略 call_assembler:在调用内部花费的时间将计入调用它的循环。