在Python中,如何在多个CPU核心上运行简单循环(适用于不同数据)的最佳方式?
我正在计算一些每年都需要处理的数据,这个过程比较耗费计算资源。我使用了 numba(效果很好)来减少运行这些计算所需的时间。不过,由于我有20年的独立数据,我想把这些数据分成5组,每组4年,这样可以在4个不同的CPU核心上同时运行。
def compute_matrices(self):
for year in self.years:
self.xs[year].compute_matrix()
在上面的代码片段中,这个函数是一个类中的方法,类里有两个属性:year 和 xs。year
只是一个整数,表示年份,而 xs
是一个交叉数据对象,里面包含了 xs.data 和 compute_matrix() 方法。
那么,有什么简单的方法可以把这些计算分配到多个核心上呢?
如果有一个像 Numba 这样的装饰器,可以自动把循环拆分开来,并在不同的进程中运行,然后把结果合并在一起,那就太好了。这种东西存在吗?
我最好的选择是使用 Python 的 multiprocessing 吗?
2 个回答
我遇到的处理复杂对象最简单的方法就是使用IPython并行计算引擎。
只需要通过以下命令启动一个Ipython集群:ipcluster start -n 4
,或者使用笔记本。
然后你就可以在不同的客户端上遍历分配给它们的xs对象。
def multicore_compute_matrices(self):
from IPython.parallel import Client
c = Client()
xs_list = []
years = sorted(self.years)
# - Ordered List of xs Objects - #
for year in years
xs_list.append(self.xs[year])
# - Compute across Clusters - #
results = c[:].map_sync(lambda x: x.compute_matrix(), xs_list)
# - Assign Results to Current Object - #
year = years[0]
for result in results:
self.xs[year].matrix = result
year += 1
墙时 %time
的结果:
%time A.compute_matrices()
Wall Time: 5.53s
%time A.multicore_compute_matrices():
Wall Time: 2.58s
这里有几个你可以考虑的东西:
NumbaPro: https://store.continuum.io/cshop/accelerate/。这基本上是增强版的Numba,支持多核和多线程的架构。不过,它的价格不便宜。
Numexpr: https://code.google.com/p/numexpr/。这是一个用于numpy数组的表达式计算器,它实现了超线程技术。
Numexpr-Numba(实验性):https://github.com/gdementen/numexpr-numba。顾名思义,这是将Numexpr与Numba结合使用的。
很多答案会依赖于你在compute_matrix
方法中做了什么。
最快(从开发时间来看)的解决方案可能就是使用multiprocessing
库来拆分你的计算。需要注意的是,如果你的compute_matrix
函数没有副作用,那么使用multiprocessing会更简单。