在Python中,如何在多个CPU核心上运行简单循环(适用于不同数据)的最佳方式?

4 投票
2 回答
1014 浏览
提问于 2025-04-18 01:27

我正在计算一些每年都需要处理的数据,这个过程比较耗费计算资源。我使用了 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() 方法。

那么,有什么简单的方法可以把这些计算分配到多个核心上呢?

  1. 如果有一个像 Numba 这样的装饰器,可以自动把循环拆分开来,并在不同的进程中运行,然后把结果合并在一起,那就太好了。这种东西存在吗?

  2. 我最好的选择是使用 Python 的 multiprocessing 吗?

2 个回答

1

我遇到的处理复杂对象最简单的方法就是使用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
3

这里有几个你可以考虑的东西:

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会更简单。

撰写回答