我有一个相当复杂的计算代码,我正在尝试加速和多线程。为了优化代码,我正在尝试找出哪些函数花费的时间最长或被调用的次数最多。
我以前没有真正分析过代码,所以我可能会遗漏一些东西。但是,我知道许多现有的分析模块由于使用 LLVM 重新编译而不能很好地与 numba 的 njit() 装饰器一起使用。
所以我的问题是:分析代码的最佳方法是什么,其中大多数函数都具有 njit() 装饰器,但有一些非 jitted 控制函数?
我遇到了 data_profiler之前,但是它似乎不再位于 conda 存储库中,我不知道如何从 conda 中的源代码构建它,或者它是否仍与其依赖项的现代版本兼容。
最佳答案
如果这作为最后的手段可能有所帮助,让我们试一试:
在 QuantFX 模块开发上花费了几十年的时间,同时使用 numba
和其他矢量化/jit 加速工具,让我分享一些经验,这被认为对我们出于类似动机的分析很方便。
与提到的 data_profiler
相反,在毫秒级,我们享受微秒级分辨率作为使用 ZeroMQ 模块的副作用,用于分布式信号/消息传递基础设施。
ZeroMQ 的所有服务都在一个核心引擎中实现,称为 Context
,但是有一个小实用程序可以独立于此工具免费重用,一个Stopwatch
- 微秒分辨率计时器类。
所以,没有什么能阻止我们:
from pyzmq import Stopwatch as MyClock
aClock_A = MyClock(); aClock_B = MyClock(); aClock_C = MyClock(); print( "ACK: A,B,C made" )
# may use 'em when "framing" a code-execution block:
aClock_A.start(); _ = sum( [ aNumOfCollatzConjectureSteps( N ) for N in range( 10**10 ) ] ); TASK_A_us = aClock_A.stop()
print( "INF: Collatz-task took {0:} [us] ".format( TASK_A_us ) )
# may add 'em into call-signatures and pass 'em and/or re-use 'em inside whatever our code
aReturnedVALUE = aNumbaPreCompiledCODE( 1234,
"myCode with a need to profile on several levels",
aClock_A, # several,
aClock_B, # pre-instantiated,
aClock_C # Stopwatch instances, so as
) # to avoid chained latencies
通过这种方式,如果确实被迫至少使用这个作为最后手段的工具,可以将任何基于Stopwatch
的分析结构“硬连线”到自己的源代码中。唯一的限制是需要符合 Stopwatch
实例的有限状态自动机,其中一旦调用了 .start()
方法,只有 .stop()
方法可能接下来出现,类似地,在尚未被 .start()
编辑的实例上调用 .stop()
方法会很自然抛出异常。
常见的 try-except-finally
脚手架将有助于确定所有 Stopwatch 实例恰好再次变为 .stop()
-ed,即使可能发生了异常.
“硬连线”分析的结构取决于您的代码执行“测试中的热点”,甚至是调用相关开销的“跨界”分析,花费在 @jit-decorated 的 native python 调用之间numba-LLVM-ed 代码并从 numba 编译代码“内部”的第一行开始(即调用调用和参数分析之间需要多长时间,由调用签名列表驱动或主要避免,通过强制执行单一的,明确的,呼号)
祝你好运。希望对您有所帮助。
关于Python:如何分析使用 numba.njit() 装饰器编写的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55213687/