2

一段时间以来,我一直在使用线程和进程来尝试加快我在 IPython 中的并行工作。我不确定我正在调用的函数有多少有用的细节,所以这里有一个 bash 但询问您是否需要更多。

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

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

基本上,obernl是观测值的参数m, ,mittidmax是代表模型的参数,观测值将与之进行比较。(n0steps是函数的固定数值参数。)函数循环遍历所有模型,并使用、和m中的相关信息mi,计算该模型匹配的概率。请注意,它相当大:它是一个包含大约 700 000 个 22x3 NumPy 数组的列表。并且大小相似。如果相关,我的普通 IPython 实例使用大约 25% 的系统内存:我的 16GB RAM 中的 4GB。ttidmaxmmidmaxtop

我试图以两种方式并行化它。首先,我尝试使用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_部分,这只是将函数逐个应用于每个元素的结果。但这比使用单核要慢。我猜这与全局解释器锁有关?

其次,我尝试使用Poolfrom multiprocessing。我初始化了一个池

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。我想它什么也没做。我也不能使用 IPython。我尝试了 Ctrl-C 一段时间,但当我通过第 300 个泳池工人时就放弃了。

4

1 回答 1

2

不是以交互方式工作吗?

multiprocessing由于它拆分进程的方式,交互性不好。这也是为什么你很难杀死它,因为它产生了这么多进程。您必须跟踪主进程才能取消它。

文档中

注意
此包中的功能要求__main__子模块可以导入该模块。这在编程指南中有介绍,但值得在这里指出。这意味着某些示例,例如multiprocessing.Pool示例将无法在交互式解释器中工作。
...
如果您尝试这样做,它实际上会以半随机方式交错输出完整的回溯,然后您可能不得不以某种方式停止主进程。

最好的解决方案可能是从命令行将其作为脚本运行。或者,IPython 有自己的并行计算系统,但我从未使用过它。

于 2013-05-14T16:26:53.470 回答