我一直在玩Birthday Problem,并提出了以下代码。问题是,即使是100万次运行,也可能需要相当长的时间。由于tick()
是最昂贵的函数,并且很好地隔离(我认为),我如何多线程while
循环部分?
来自c++ openmp背景,我可能会使用#pragma omp parallel
,但我不知道如何在python中执行此操作,尤其是{ {1}}问题
我还有其他方法可以提高效果吗?
GIL
ncalls tottime percall cumtime percall filename:lineno(function)
1000000 10.320 0.000 21.736 0.000 sim.py:29(tick)
24617823 6.931 0.000 9.209 0.000 sim.py:8(getday)
24617823 2.278 0.000 2.278 0.000 {method 'randint' of 'mtrand.RandomState' objects}
23617823 2.115 0.000 2.115 0.000 {method 'add' of 'set' objects}
1 0.983 0.983 22.967 22.967 sim.py:12(main)
999999 0.105 0.000 0.105 0.000 {method 'append' of 'list' objects}
答案 0 :(得分:2)
尝试使用此代码,其中main()下的padding = 'SAME'
子句选择原始版本或mp版本...
if
在我的14核机器运行时间从21秒到1.75秒,这非常接近理论最大值。
您可以尝试在多处理中使用几种不同的并行方法。请参阅https://docs.python.org/2/library/multiprocessing.html 16.6.2.9。流程池
请注意,可选的chunksize参数会极大地影响性能。使用import numpy as np
import multiprocessing as mp
def getday():
return np.random.randint(1, 366)
def main():
size = 1000000
if 0: # original version
popSize = [tick()]
while len(popSize) < size:
popSize.append(tick())
else: # multithreaded
pool = mp.Pool()
popSize = pool.map(tick, range(size))
print "Iterations %d" % len(popSize)
print "Average pop size %d" % (sum(popSize) / len(popSize))
print "Min pop size %d" % min(popSize)
print "Max pop size %d" % max(popSize)
def tick(dummy=None):
days = set()
day = getday()
while day not in days:
days.add(day)
day = getday()
return len(days)
if __name__ == '__main__':
main()
似乎并不需要加速,但如果您使用map
,则需要将imap
设置为100以查看加速。