我有一个程序,可以从一个完整的包装中随机选择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()
答案 0 :(得分:0)
对于IDLE无法正确运行多处理器启动指令的原因,我没有任何答案,但我相信将执行时间加倍的答案在于我要处理的问题类型。也许其他人可以发表评论,但是在我看来,与向队列中添加和从队列中删除项目所涉及的开销非常高,因此,当与队列相比,通过队列传递的数据量较小时,可以最好地实现性能改进。获取该数据所需的处理方式。
在我的程序中,我正在创建并传递10 ** 7个数据项,我想这是通过Queue传递此数量项的开销,这会扼杀通过单独的进程获取数据带来的任何性能改进。通过使用地图,似乎所有10 ^ 7数据项都需要存储在地图中,然后才能进行任何进一步的处理。根据使用地图和处理大量数据的开销,这可能会提高性能,但暂时我将坚持使用原始的原始的,单处理的代码。