(I)Python中处理大数据块的并行性



一段时间以来,我一直在努力研究线程和进程,试图加快我在ippython中非常并行的工作。我不确定我调用的函数有多少细节是有用的,所以这里有一个bash,但如果您需要更多,请询问。

我的函数的调用签名看起来像

def intersplit_array(ob,er,nl,m,mi,t,ti,dmax,n0=6,steps=50):

基本上,obernl是观测值的参数,mmittidmax是代表将与观测值进行比较的模式的参数。(n0steps是该函数的固定数值参数。)该函数循环遍历m中的所有模型,并使用mittidmax中的相关信息,计算出该模型匹配的概率。注意m是相当大的:它是一个大约700000个22x3 NumPy数组的列表。midmax大小相近。如果相关的话,我的正常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有自己的并行计算系统,但我从未使用过它。

最新更新