如何停止numpy的多线程?

65

我需要定期在与部门其他人共享的计算服务器上运行作业,当我启动10个任务时,我希望它只使用10个核心而不是更多; 单个核心运行可能需要更长时间,但我只是不希望它侵占其他人的领土,这将需要我renice这些作业等等。我只想要10个可靠的核心就好了。

我使用的是基于Python 2.7.3和numpy 1.6.1的Redhat上的Enthought 7.3-1,但问题更为普遍。


3
我很确定numpy没有使用多线程,因此没有需要关闭的选项。 - Winston Ewert
2
为进程设置 CPU 亲和性。 - jfs
21
@WinstonEwert说错了。在多核CPU上使用np.dot计算大型矩阵时,所使用的库可能会利用多个CPU。 - jfs
1
非常感谢。现在我知道要搜索什么,我找到了另一个页面,似乎回答了我的问题:https://dev59.com/MXI_5IYBdhLWcg3wAd82 - MasDaddy
5个回答

57

希望这可以解决您可能遇到的所有情况和系统问题。

  1. 使用 numpy.__config__.show() 查看您是否正在使用 OpenBLAS 或 MKL。

从此开始,您有几种方法可以解决这个问题。

2.1. 终端命令行方式:export OPENBLAS_NUM_THREADS=1export MKL_NUM_THREADS=1

2.2(这是我首选的方法)在您的 Python 脚本中 import os 并添加以下一行代码:os.environ['OPENBLAS_NUM_THREADS'] = '1'os.environ['MKL_NUM_THREADS'] = '1'

注意:在设置 os.environ[VAR] 时,线程数必须是字符串!而且,在导入 numpy/scipy 之前可能需要设置此环境变量。

除 openBLAS 或 MKL 之外,可能还有其他选项,但第1步将帮助您找出答案。


3
太神奇了。当我尝试使用multiprocessing.Pool并行化一批fftpack和odeint模拟时,它给了我高达600倍的速度提升!但是,在我到达笔记本电脑的多处理部分之前,速度提升已经生效了。显然,某些OpenBLAS线程阻止了正确的向量化。 - tsbertalan
2
另一个惊人的事情是,在更改后,htop报告的利用率实际上更低,因此似乎确实使用了一些不同的代码路径;也许是某些更好地利用我的Xeon E5-1660v4矢量扩展的东西。 - tsbertalan

41

MKL_NUM_THREADS环境变量设置为1。如您所料,此环境变量控制Math Kernel Library的行为,该库作为Enthought的numpy构建的一部分包含。

我只需在启动文件.bash_profile中使用export MKL_NUM_THREADS=1即可完成此操作。您还可以从脚本内部执行此操作,以使其成为进程特定。


谢谢。这比为每个进程设置任务要容易得多。 - MasDaddy
我尝试简要总结了在GitHub Gist中设置的事项:https://gist.github.com/EricCousineau-TRI/8a2d1550f5fa4be4fed87d55a522dbf2 - Eric Cousineau

21

如果您想动态设置线程数量,而不是通过环境变量全局设置,也可以执行以下操作:

import mkl
mkl.set_num_threads(2)

5
Linux/OpenBLAS怎么样? - Joey Gao

12
在较新版本的numpy中,我发现还需要设置NUMEXPR_NUM_THREADS=1。在我的操作中,仅设置该项就足够了,但在某些情况下您可能需要同时设置MKL_NUM_THREADS=1

4
值得一提的是,我需要设置 OMP_NUM_THREADS 变量(参考 https://dev59.com/jl0a5IYBdhLWcg3wCEww#31622299)。 - dtk

-9

对我来说,解决方案很简单,就是停止使用numpy.dot

import numpy as np

a = np.random.rand(1e6)
b = np.random.rand(1e6, 10)

# potentially uses multiple threads
dotted = np.dot(a, b)

# single-thread
summed = np.sum(a[:, np.newaxis] * b, axis=0)

assert np.all(dotted == summed)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接