上下文:我有一个分散在我的引擎中的数组(此时有4个引擎),想要将一个函数应用于数组中的每个点,以进行任意数量的迭代并收集来自引擎的结果数组并对其进行分析。
例如,我有分散的数据点数组和每个数据点的迭代次数:
data_points = range(16)
iterations = 10
dview.scatter('points', data_points)
我有一个用户提供的功能,它被推送到引擎:
def user_supplied_function(point):
return randint(0, point)
dview.push(dict(function_one = user_supplied_function))
我的结果列表和并行执行:
result_list = []
for i in range(iterations):
%px engine_result = [function_one(j) for j in points]
result_list.append(dview.gather('engine_result'))
问题:这是有效的,我从引擎中得到了我想要的结果,但随着迭代次数的增加,循环执行的时间越来越长。到50点的1000次迭代需要超过15秒才能完成。而此任务的顺序版本只需不到一秒钟。
知道可能导致这种情况的原因是什么?可能是来自gather()
的消息的开销吗?如果是这样,任何人都可以建议任何解决方案?
答案 0 :(得分:0)
想出来。毕竟,这是gather()
和.append()
的开销。最简单的解决方法是在引擎完成工作后gather()
,而不是每次迭代都这样做。
<强>解决方案强>
%autopx
engine_result = []
for i in xrange(iterations):
engine_result += [[function_one(j) for j in points]]
%autopx
result_list = list(dview.gather('engine_result'))
然而,这会导致结果列表格式不正确的列表,其中每个引擎的结果彼此相邻放置,而不是按迭代次数排序。以下命令分发列表并展平每次迭代的子列表。
gathered_list = [None] * iterations
gathered_list = [[result_list[j * iterations + i] for j in xrange(len(result_list) / iterations)] for i in xrange(iterations)]
gathered_list = [reduce(lambda x, y: x.extend(y) or x, z) for z in gathered_list]