3

我有一个 python 脚本,它必须对大型数据集进行许多排列,对每个排列进行评分,并且只保留得分最高的排列。数据集是如此之大,以至于这个脚本需要将近 3 天的时间才能运行。

当我在 Windows 中检查系统资源时,只有 12% 的 CPU 被使用,并且 8 个内核中只有 4 个在工作。即使我将 python.exe 进程置于最高优先级,这也不会改变。

我的假设是,将更多的 CPU 使用率专用于运行脚本可以使其运行得更快,但我的最终目标是将运行时间减少至少一半。是否有 python 模块或一些代码可以帮助我做到这一点?顺便说一句,这听起来像是一个可以从更智能的算法中受益的问题吗?

先感谢您!

4

5 回答 5

3

有几种方法可以解决这个问题,但请查看多处理模块。这是一个用于创建多个进程的标准库模块,类似于线程,但没有 GIL 的限制。

您还可以查看优秀的Celery库。这是一个分布式任务队列,有很多很棒的功能。它的安装非常简单,而且很容易上手。

于 2013-04-05T14:44:33.247 回答
1

我可以用一个简单的代码示例来回答 HOW-TO。当它正在运行时,运行 /bin/top 并查看您的进程。做起来很简单。请注意,我什至包括了如何在键盘中断之后进行清理——否则,您的子进程将继续运行,您将不得不手动终止它们。

from multiprocessing import Process
import traceback
import logging 
import time

class AllDoneException(Exception):
    pass

class Dum(object):
    def __init__(self):
        self.numProcesses = 10    
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(logging.StreamHandler())

    def myRoutineHere(self, processNumber):
        print "I'm in process number %d" % (processNumber)
        time.sleep(10)
        # optional: raise AllDoneException  

    def myRoutine(self):
        plist = []
        try:
            for pnum in range(0, self.numProcesses):
                p = Process(target=self.myRoutineHere, args=(pnum, ))
                p.start()
                plist.append(p)
            while 1:
                isAliveList = [p.is_alive() for p in plist]
                if not True in isAliveList:
                    break
                time.sleep(1)
        except KeyboardInterrupt:
            self.logger.warning("Caught keyboard interrupt, exiting.")
        except AllDoneException:
            self.logger.warning("Caught AllDoneException, Exiting normally.")
        except:
            self.logger.warning("Caught Exception, exiting: %s" % (traceback.format_exc()))
        for p in plist:
            p.terminate()

d = Dum()
d.myRoutine()
于 2013-04-05T15:00:51.057 回答
0

您应该生成新进程而不是线程来利用 CPU 中的内核。我的一般规则是每个核心一个进程。因此,您将问题输入空间拆分为可用内核的数量,每个进程都获得问题空间的一部分。

多处理是最好的。您也可以使用Parallel Python

于 2013-04-05T14:46:24.160 回答
0

派对很晚 - 但除了使用多处理模块外,如爬行动物所说,还要确保设置“亲和力”。

一些 python 模块对其进行了修改,有效地降低了 Python 可用的内核数量:

https://stackoverflow.com/a/15641148/4195846

于 2017-06-29T21:55:06.950 回答
-1

由于全局解释器锁定,一个 Python 进程无法利用多个内核。但是,如果您可以以某种方式并行化您的问题(无论如何您都应该这样做),那么您可以使用multiprocessing产生与您拥有的内核一样多的 Python 进程并在每个子进程中处理该数据。

于 2013-04-05T14:44:43.313 回答