Python多重处理使OSX脱颖而出

时间:2018-10-23 15:11:18

标签: python-3.x macos multiprocessing

我有一个程序,可以从一个完整的包装中随机选择13张牌,并分析手的形状,点数和其他一些对于桥牌游戏很重要的特征。该程序将在大约5分钟内选择并分析10 ** 7手。检查活动监视器显示,在执行过程中,CPU(6核处理器)将其9%的时间用于程序,并将其90%的时间用于空闲。因此,它似乎是进行多处理的主要候选对象,我使用队列创建了一个多处理版本,以将信息从每个进程传递回主程序。解决了IDLE不起作用的问题后,它将进行多处理(我现在使用PyCharm运行它),并且在完成过程之前对进程进行连接会冻结程序,我就可以开始工作。

但是,我使用5、10、25或50个进程并不重要,结果始终相同。 CPU将其大约18%的时间用于程序,大约有75%的空闲时间,而执行时间在10分钟多一点的时间内是两倍多

谁能解释我如何使进程占用更多的CPU时间以及如何获得执行时间来反映这一点?以下是该程序的相关部分:

import random
import collections
import datetime
import time

from math import log10
from multiprocessing import Process, Queue


NUM_OF_HANDS = 10**6
NUM_OF_PROCESSES = 25


def analyse_hands(numofhands, q):

#code remove as not relevant to the problem

        q.put((distribution, points, notrumps))


if __name__ == '__main__':

    processlist = []
    q = Queue()

    handsperprocess = NUM_OF_HANDS // NUM_OF_PROCESSES
    print(handsperprocess)
    # Set up the processes and get them to do their stuff
    start_time = time.time()
    for _ in range(NUM_OF_PROCESSES):
        p = Process(target=analyse_hands, args=((handsperprocess, q)))
        processlist.append(p)
        p.start()

    # Allow q to get a few items
    time.sleep(.05)
    while not q.empty():
        while not q.empty():
            #code remove as not relevant to the problem

        # Allow q to be refreshed so allowing all processes to finish before
        # doing a join.  It seems that doing a join before a process is
        # finished will cause the program to lock
        time.sleep(.05)
        counter['empty'] += 1

    for p in processlist:
        p.join()

    while not q.empty():
        # This is never executed as all the processes have finished and q
        # emptied before the join command above.

        #code remove as not relevant to the problem       

    finish_time = time.time()

1 个答案:

答案 0 :(得分:0)

对于IDLE无法正确运行多处理器启动指令的原因,我没有任何答案,但我相信将执行时间加倍的答案在于我要处理的问题类型。也许其他人可以发表评论,但是在我看来,与向队列中添加和从队列中删除项目所涉及的开销非常高,因此,当与队列相比,通过队列传递的数据量较小时,可以最好地实现性能改进。获取该数据所需的处理方式。

在我的程序中,我正在创建并传递10 ** 7个数据项,我想这是通过Queue传递此数量项的开销,这会扼杀通过单独的进程获取数据带来的任何性能改进。通过使用地图,似乎所有10 ^ 7数据项都需要存储在地图中,然后才能进行任何进一步的处理。根据使用地图和处理大量数据的开销,这可能会提高性能,但暂时我将坚持使用原始的原始的,单处理的代码。