使用多处理模块时,如何提高CPU利用率?

时间:2014-10-10 00:17:51

标签: python performance python-3.x multiprocessing

我正在使用Python 3.4,对内存中的分区数据执行简单搜索,并尝试派生进程以利用所有可用的处理能力。我说天真,因为我确信还有其他一些可以改善性能的事情,但这些潜力超出了手头的问题范围。

我正在测试的系统是Windows 7 x64环境。

我希望实现的是跨cpu_count() - 1内核的相对均匀,同时分布(读数表明,针对所有内核而非n-1内核的分发不会因基线操作系统进程而显示任何其他改进) 。因此,对于4核机器,75%的固定CPU使用率。

我所看到的(使用Windows任务管理器&#39;性能标签&#39;以及&#39;进程标签&#39;)是我从未实现超过25%的系统专用cpu利用率< / strong>并且进程视图显示计算一次发生一个核心,在分叉进程之间每隔几秒切换一次。

我还没有为时间安排代码,但我很确定我的主观观察是正确的,因为我没有达到我预期的性能提升(在i5 3320m上增加3倍)。

我还没有在Linux上测试过。

根据提供的代码: - 如何实现75%的CPU利用率?

#pseudo code
def search_method(search_term, partition):
    <perform fuzzy search>
    return results

partitions = [<list of lists>]
search_terms = [<list of search terms>]

#real code
import multiprocessing as mp

pool = mp.Pool(processes=mp.cpu_count() - 1)

for search_term in search_terms:
    results = []
    results = [pool.apply(search_method, args=(search_term, partitions[x])) for x in range(len(partitions))]

1 个答案:

答案 0 :(得分:3)

你实际上并没有在这里同时做任何事情,因为你正在使用pool.apply,这将阻止你传递给它的任务完成。因此,对于partitions中的每个项目,您在search_method内的某个进程中运行pool,等待它完成,然后转到下一个项目。这完全符合您在Windows流程管理器中看到的内容。您想要pool.apply_async代替:

for search_term in search_terms:
    results = []
    results = [pool.apply_async(search_method, args=(search_term, partitions[x])) for x in range(len(partitions))]

    # Get the actual results from the AsyncResult objects returned.
    results = [r.get() for r in results]

或者更好的是,使用pool.map(以及functools.partial来启用将多个参数传递给worker函数):

from functools import partial
...

for search_term in search_terms:
    func = partial(search_method, search_term)
    results = pool.map(func, partitions)