2 回答
TA贡献1777条经验 获得超3个赞
正如您提到的,Python 有一个“全局解释器锁”(GIL),可以防止Python 代码的两个线程同时运行。多线程可以加速 IO 密集型任务的原因是 Python 在侦听网络套接字或等待磁盘读取时释放 GIL。因此,GIL 不会阻止计算机同时完成两批工作,它会阻止同一 Python 进程中的两个 Python 线程同时运行。
在您的示例中,您使用 numpy 和 scipy。这些主要是用 C 编写的,并利用用 C/Fortran/Assembly 编写的库(BLAS、LAPACK 等)。当您对 numpy 数组执行操作时,类似于监听套接字,因为GIL 被释放。当 GIL 被释放并且 numpy 数组操作被调用时,numpy 开始决定如何执行工作。如果需要,它可以生成其他线程或进程,并且它调用的 BLAS 子例程可能会生成其他线程。如果您想从源代码编译 numpy,则可以在构建时准确配置是否/如何完成此操作。
因此,总而言之,您已经找到了规则的例外。如果您仅使用纯 Python 函数重复该实验,您将得到完全不同的结果。
TA贡献1811条经验 获得超5个赞
Python 线程是真正的线程,只是解释器中不能同时存在两个线程(这就是 GIL 的含义)。代码的本机部分可以很好地并行运行,而不会在多个线程上发生争用,只有当深入解释器时,它们才必须在彼此之间进行序列化。
仅将所有 CPU 核心加载到 100% 的事实并不能证明您正在“高效”使用机器。您需要确保 CPU 使用率不是由上下文切换引起的。
如果您切换到多处理而不是线程(它们非常相似),则不必双重猜测,但是在线程之间传递时必须对有效负载进行封送。
所以无论如何都需要测量一切。
添加回答
举报