一段时间以来,我一直在努力研究线程和进程,试图加快我在ippython中非常并行的工作。我不确定我调用的函数有多少细节是有用的,所以这里有一个bash,但如果您需要更多,请询问。
我的函数的调用签名看起来像
def intersplit_array(ob,er,nl,m,mi,t,ti,dmax,n0=6,steps=50):
基本上,ob
、er
和nl
是观测值的参数,m
、mi
、t
、ti
和dmax
是代表将与观测值进行比较的模式的参数。(n0
和steps
是该函数的固定数值参数。)该函数循环遍历m
中的所有模型,并使用mi
、t
、ti
和dmax
中的相关信息,计算出该模型匹配的概率。注意m
是相当大的:它是一个大约700000个22x3 NumPy数组的列表。mi
和dmax
大小相近。如果相关的话,我的正常ippython实例在top
中使用了大约25%的系统内存:我的16GB RAM中的4GB。
我试着用两种方式来并行化。首先,我尝试使用SciPy Cookbook中给出的parallel_map
函数。我打了电话
P = parallel_map(lambda i: intersplit_array(ob,er,nl,m[i+1],mi[i:i+2],t[i+1],ti[i:i+2],dmax[i+1],range(1,len(m)-1))
运行,并提供正确的答案。如果没有parallel_
部分,这只是将函数逐个应用于每个元素的结果。但这比使用单核要慢。我猜这与全局解释器锁有关?
第二,我尝试使用multiprocessing
中的Pool
。我用
p = multiprocessing.Pool(6)
然后试图用
调用我的函数P = p.map(lambda i: intersplit_array(ob,er,nl,m[i+1],mi[i:i+2],t[i+1],ti[i:i+2],dmax[i+1],range(1,len(m)-1))
首先得到一个错误。
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
查看top
,然后我看到所有额外的ipython
进程,每个进程显然占用25%的RAM(这是不可能的,因为我仍然有4GB空闲)并使用0%的CPU。我猜它什么也没做。我也不会用python。我尝试了Ctrl-C一段时间,但当我通过了第300个pool worker时放弃了。
不交互工作吗?
multiprocessing
不能很好地交互,因为它分割进程的方式。这也是为什么你很难杀死它,因为它产生了很多进程。您必须跟踪主进程才能取消它。
来自文档:
注意
这个包中的功能要求__main__
模块可以被子模块导入。这在编程指南中有介绍,但在这里值得指出。这意味着一些示例,如multiprocessing.Pool
示例将无法在交互式解释器中工作。...
如果你尝试这样做,它实际上会以半随机的方式输出完整的回溯,然后你可能不得不以某种方式停止主进程。
最好的解决方案可能是从命令行将其作为脚本运行。另外,IPython有自己的并行计算系统,但我从未使用过它。