背景 当使用scikit learn在大型数据集上执行令人尴尬的并行任务时,在高性能计算(HPC)环境中的集群上执行此任务非常方便。Scikit learn允许用户通过n_jobs参数指定并行使用的内核数量,从而为并行化提供支持。原则上,这将使分析管道中使用的内核数量与HPC环境中调度程序请求的处理器数量相匹配变得简单
问题
它向我指出,每个作业运行的进程数(即7个)超过了我请求的处理器数(即2个),尽管我实际上已将scikit learn的n_job参数设置为2。正如我所知道的,结果是这些进程现在相互阻止使用有限的计算资源(我想象有点像音乐椅),从而产生不必要的开销,并使集群的使用效率低下。通过运行pstree PID
检测到线程数
问题 额外的5个流程来自哪里?如何控制scikit learn中的进程数以匹配实际分配给群集作业的处理器数
代码示例 我创建了一个小示例来说明这种行为(Python 3.6.8、numpy 1.18.1、scikit learn 0.20.3)
#!/usr/bin/env python
import numpy as np
import os
import time
from sklearn.model_selection import permutation_test_score
from sklearn import datasets, svm
n_folds = 3
n_perm = 12000
n_jobs = 2 # The number of tasks to run in parallel
n_cpus = 2 # Number of CPUs assigned to this process
pid = os.getpid()
print("PID: %i" % pid)
print("loading iris dataset")
X, y = datasets.load_iris(return_X_y=True)
# Control which CPUs are made available for this script
cpu_arg = ''.join([str(ci) + ',' for ci in list(range(n_cpus))])[:-1]
cmd = 'taskset -cp %s %i' % (cpu_arg, pid)
print("executing command '%s' ..." % cmd)
os.system(cmd)
t1 = time.time()
res = permutation_test_score(svm.SVC(kernel='linear'), X, y, cv=n_folds,
n_permutations=n_perm, n_jobs=n_jobs,
verbose=3)
t_delta = time.time() - t1
ips = n_perm / t_delta
print("number of iterations per second: %.02f it/s" % ips)
在使用htop
进行检查时,似乎我确实通过n_jobs=2
和n_cpus=2
-2请求的CPU数量正以100%的速度运行。但是,当我使用pstree PID
查看线程时,我可以看到6个进程正在运行,而不是预期的两个进程
仅请求n_jobs=1
和n_cpus=1
会导致htop
显示一个CPU 100%繁忙,并且pstree PID
同样显示仅运行一个处理,如预期的那样
其他信息和进一步尝试
有关我的操作系统的一些信息,请参见uname -a
:
Linux COMPUTERNAME 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
。。。关于CPU,请参见lscpu | grep -e CPU -e core
:
CPU op-mode(s): 32-bit, 64-bit
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
CPU family: 6
Model name: Intel(R) Xeon(R) W-2123 CPU @ 3.60GHz
CPU MHz: 1200.050
CPU max MHz: 3900,0000
CPU min MHz: 1200,0000
NUMA node0 CPU(s): 0-7
我的示例代码现在允许使用taskset
命令控制可用于代码执行的CPU数量。因此,我可以分别处理scikit learn(n_jobs
)中请求并行运行的任务数和可用CPU数(n_cpus
)。这使我能够相互比较四种情况:
n_jobs=1
和n_cpus=1
:360.24it/s,htop
显示一个CPU正忙,pstree PID
显示一个线程正在运行李>n_jobs=2
和{pstree PID
显示6个线程正在运行李>n_jobs=2
和n_cpus=1
:336.80 it/s,htop
显示一个CPU正忙,pstree PID
显示6个线程正在运行李>n_jobs=1
和n_cpus=2
:358.60 it/s,htop
显示一个CPU正忙,pstree PID
显示一个线程正在运行李>似乎pstree
始终取决于scikit学习API中请求的线程数。由htop
显示为活动的CPU数量是脚本和可用且也在使用的CPU数量。因此,只有场景2会导致两个CPU忙。同样,只有在CPU可用且已使用的情况下(也包括场景2),处理速度(以每秒迭代次数衡量)才会在并行情况下提高。关键的是,根据pstree
的说法,线程的数量是6个,因此大于CPU的数量,这并不表明它们在有限的CPU中相互干扰。只有场景3显示,当请求两个作业但只有一个CPU可用时,处理速度似乎较慢。这比场景1慢
我开始怀疑pstree
是否真的是对并行处理效率的一个很好的诊断,以及它与htop
有何不同
目前没有回答
相关问题 更多 >
编程相关推荐