You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scipy lsim/lsim2性能优化:单核心低资源下高效运行需求

问题:单核心/低资源环境下高效运行scipy.signal.lsim

我在Python脚本中使用scipy的lsim函数进行系统模型仿真,目前遇到的问题是lsim会在多核心上生成大量子进程,导致CPU负载过高,这一点可从下方性能分析日志中体现。我在多人共享的处理机上运行脚本,改用lsim2不会生成子进程,但运行速度慢到难以接受。请问如何在单核心/少资源的情况下快速运行lsim?

性能分析日志片段

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     3740   25.422    0.007   51.062    0.014 /grid/common/pkgs/python/v3.7.2/lib/python3.7/site-packages/scipy/signal/ltisys.py:1870(lsim)
 26753891   21.519    0.000   21.519    0.000 {built-in method numpy.dot}
       12    0.001    0.000   21.450    1.788 /grid/common/pkgs/python/v3.7.2/lib/python3.7/subprocess.py:431(run)
       12    0.000    0.000   21.265    1.772 /grid/common/pkgs/python/v3.7.2/lib/python3.7/subprocess.py:895(communicate)
       24    0.000    0.000   21.265    0.886 /grid/common/pkgs/python/v3.7.2/lib/python3.7/subprocess.py:985(wait)
       24    0.000    0.000   21.265    0.886 /grid/common/pkgs/python/v3.7.2/lib/python3.7/subprocess.py:1592(_wait)
       12    0.000    0.000   21.264    1.772 /grid/common/pkgs/python/v3.7.2/lib/python3.7/subprocess.py:1579(_try_wait)

解决方案

  • 强制numpy使用单核心:从日志看numpy.dot占用大量时间,numpy默认会启用多线程加速,这是高CPU负载的核心原因之一。在导入numpy和scipy前设置环境变量限制线程数:

    import os
    # 限制各类线性代数库的线程数为1
    os.environ["OMP_NUM_THREADS"] = "1"
    os.environ["OPENBLAS_NUM_THREADS"] = "1"
    os.environ["MKL_NUM_THREADS"] = "1"
    os.environ["VECLIB_MAXIMUM_THREADS"] = "1"
    os.environ["NUMEXPR_NUM_THREADS"] = "1"
    
    # 之后再导入scipy和numpy
    import numpy as np
    from scipy.signal import lsim
    
  • 优化lsim调用方式:日志显示lsim被调用了3740次,频繁的函数调用会增加开销。如果是循环调用处理多个仿真任务,建议将输入信号批量处理,比如把多个输入合并为二维数组,一次性传入lsim,减少调用次数和子进程创建频率。

  • 升级scipy版本:你当前使用的scipy版本适配Python3.7,属于较旧版本。新版本的scipy(1.7+)对lsim的实现做了优化,可能减少了不必要的子进程创建,同时提升了单核心下的运行效率。

  • 手动实现核心仿真逻辑:如果你的系统是简单的线性时不变系统,可以基于状态空间模型的递推公式自行实现仿真逻辑,完全避免lsim的额外开销和子进程问题。例如:

    def custom_lsim(A, B, C, D, u, t):
        x = np.zeros(A.shape[0])
        y = []
        dt = t[1] - t[0]
        for i in range(len(t)):
            x = x + dt * (A @ x + B @ u[i])
            y.append(C @ x + D @ u[i])
        return np.array(y)
    

    注意需根据你的系统模型调整公式,适合固定步长的仿真场景。

内容的提问来源于stack exchange,提问作者Daiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:35:02