我需要定期在与部门其他人共享的计算服务器上运行作业,当我启动10个任务时,我希望它只使用10个核心而不是更多; 单个核心运行可能需要更长时间,但我只是不希望它侵占其他人的领土,这将需要我renice这些作业等等。我只想要10个可靠的核心就好了。
我使用的是基于Python 2.7.3和numpy 1.6.1的Redhat上的Enthought 7.3-1,但问题更为普遍。
我需要定期在与部门其他人共享的计算服务器上运行作业,当我启动10个任务时,我希望它只使用10个核心而不是更多; 单个核心运行可能需要更长时间,但我只是不希望它侵占其他人的领土,这将需要我renice这些作业等等。我只想要10个可靠的核心就好了。
我使用的是基于Python 2.7.3和numpy 1.6.1的Redhat上的Enthought 7.3-1,但问题更为普遍。
希望这可以解决您可能遇到的所有情况和系统问题。
numpy.__config__.show()
查看您是否正在使用 OpenBLAS 或 MKL。从此开始,您有几种方法可以解决这个问题。
2.1. 终端命令行方式:export OPENBLAS_NUM_THREADS=1
或 export 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步将帮助您找出答案。
将MKL_NUM_THREADS
环境变量设置为1。如您所料,此环境变量控制Math Kernel Library的行为,该库作为Enthought的numpy
构建的一部分包含。
我只需在启动文件.bash_profile中使用export MKL_NUM_THREADS=1
即可完成此操作。您还可以从脚本内部执行此操作,以使其成为进程特定。
如果您想动态设置线程数量,而不是通过环境变量全局设置,也可以执行以下操作:
import mkl
mkl.set_num_threads(2)
NUMEXPR_NUM_THREADS=1
。在我的操作中,仅设置该项就足够了,但在某些情况下您可能需要同时设置MKL_NUM_THREADS=1
。OMP_NUM_THREADS
变量(参考 https://dev59.com/jl0a5IYBdhLWcg3wCEww#31622299)。 - dtk对我来说,解决方案很简单,就是停止使用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)
np.dot
计算大型矩阵时,所使用的库可能会利用多个CPU。 - jfs