ipython parallel client.map比python慢得多;地图;?

ipython parallel client.map比python慢得多;地图;?,python,parallel-processing,ipython,Python,Parallel Processing,Ipython,我试图理解为什么我的负载平衡视图映射语句在两个内核上执行需要22秒,而不是使用内置映射在一个内核上执行10毫秒。我知道并行工作有一个与之相关的开销,但这不能解释额外的22秒。我做错了什么 我在Intel Core2Duo Mac上运行Python 2.7。OS X.10 In [4]: from IPython.parallel import Client In [5]: rc = Client() In [6]: lview = rc.load_balanced_view() In [7

我试图理解为什么我的负载平衡视图映射语句在两个内核上执行需要22秒,而不是使用内置映射在一个内核上执行10毫秒。我知道并行工作有一个与之相关的开销,但这不能解释额外的22秒。我做错了什么

我在Intel Core2Duo Mac上运行Python 2.7。OS X.10

In [4]: from IPython.parallel import Client

In [5]: rc = Client()

In [6]: lview = rc.load_balanced_view()

In [7]: lview.block = True

In [8]: %timeit map(lambda x:x**10, range(3000))
100 loops, best of 3: 9.91 ms per loop

In [9]: %timeit lview.map(lambda x:x**10, range(3000))
1 loops, best of 3: 22.8 s per loop

只是有一大堆开销。对于您执行的每个循环,您必须通过消息队列将作业发送给工人。如果您更智能地分发作业,它将更高效(但仍然没有单线程版本那么高效):

如果您的工作负载足够大,并行化将获得回报:

In [10]: %timeit lview.map(lambda i:len([x**10 for x in range(i * 500000)]), range(6))
1 loops, best of 3: 2.86 s per loop

In [11]: %timeit map(lambda x:x**10, range(3000000))
1 loops, best of 3: 3.41 s per loop

正如univerio所指出的,有相当大的开销。使用非常快的任务对IPython.parallel进行测试将导致性能不佳。您的任务几乎不需要花费时间来完成,甚至比简单的开销都要简单。另一方面,如果每个任务需要一秒钟才能完成,那么IPython.parallel将更有用。请记住,该系统的设计目的不仅是为了在多个内核之间分发任务,还可以在多台计算机之间分发任务,这些计算机可能具有非常不同的环境,不运行预共享代码,并且不一定具有共享内存或磁盘。在过去,我有一个控制器将任务分配给不同城市中运行不同Python版本和不同操作系统的许多计算机上的300个CPU。所有这些都需要相当大的开销。例如,当您发送任务时,您正在发送它所需的代码和数据

然而,另一个问题是IPython的并行系统需要针对您所给它的任务类型进行配置。特别是,ipcontroller配置中的高水位线(HWM)设置对较小任务的性能有显著影响。默认情况下,HWM设置为1,这意味着控制器向每个iEngine工作进程发送一个任务,并且在第一个任务返回给该工作进程之前,不会向该工作进程发送新任务。这是最好的负载平衡,因为这意味着如果任务需要不同的时间,那么工人每次完成他们正在处理的任务时都会得到一个新任务,速度更快的工人会得到更多的任务。在某些情况下,这可能非常缓慢

但是,如果您的任务很快,则意味着开销要大得多。在这些情况下,将HWM设置为更高的值可能很有用。HWM本质上是一个设置,用于设置一个引擎上允许有多少任务未完成。将其设置为10,控制器将向每个引擎发送10个任务,然后在引擎低于10个未完成任务时(单独)发送新任务

对于大量非常快速的任务,一个特别有用的设置是0的特殊设置。在这种情况下,控制器一次将所有任务分配给工人,然后等待他们返回


此设置是ipcontroller_config.py中的c.TaskScheduler.hwm。

可以使用
LoadBalancedView
chunksize
参数:
lview.map(lambda x:x**10,范围(10000),chunksize=2000)
In [10]: %timeit lview.map(lambda i:len([x**10 for x in range(i * 500000)]), range(6))
1 loops, best of 3: 2.86 s per loop

In [11]: %timeit map(lambda x:x**10, range(3000000))
1 loops, best of 3: 3.41 s per loop