Lah*_*rah 8 python pool multiprocessing
所以我过去几天一直在搞乱python的多处理库,我真的很喜欢处理池.它易于实现,我可以想象很多用途.我之前已经完成了几个我已经听过的项目以熟悉它,并且最近完成了一个蛮力游戏的程序.
Anywho,我正在执行一个执行时间计算,总结100万到200万单线程和处理池之间的所有素数.现在,对于hangman cruncher来说,将游戏放入处理池可以将执行时间提高大约8倍(i7有8个核心),但是当研究出这些素数时,它实际上将处理时间增加了近4倍.
谁能告诉我为什么会这样?以下是有兴趣查看或测试它的人的代码:
#!/user/bin/python.exe
import math
from multiprocessing import Pool
global primes
primes = []
def log(result):
global primes
if result:
primes.append(result[1])
def isPrime( n ):
if n < 2:
return False
if n == 2:
return True, n
max = int(math.ceil(math.sqrt(n)))
i = 2
while i <= max:
if n % i == 0:
return False
i += 1
return True, n
def main():
global primes
#pool = Pool()
for i in range(1000000, 2000000):
#pool.apply_async(isPrime,(i,), callback = log)
temp = isPrime(i)
log(temp)
#pool.close()
#pool.join()
print sum(primes)
return
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
它当前将在单个线程中运行,以运行处理池,取消注释池语句并注释掉main for循环中的其他行.
Sin*_*ion 14
最有效的使用方法multiprocessing
是将工作分成n个相等大小的块,其中n为池的大小,大约应该是系统中的核心数.这样做的原因是启动子进程并在它们之间进行通信的工作量非常大.如果工作的大小与工作块的数量相比较小,则IPC的开销变得很大.
在您的情况下,您要求多处理单独处理每个素数.处理问题的一种更好的方法是为每个工作者传递一系列值(可能只是一个起始值和结束值),并让它返回它找到的范围内的所有素数.
在确定肥胖型素数的情况下,所做的工作与成长的初始值,所以你可能不希望总范围划分成恰好n块,而是ñ*K等于块,其中k一些合理的,这样,当一些工人在别人之前完成工作时,剩下的工作还有很多,而且可以在所有工人之间有效平衡.
编辑:这是一个改进的示例,用于显示该解决方案的外观.我已经尽可能少地改变了,所以你可以比较苹果和苹果.
#!/user/bin/python.exe
import math
from multiprocessing import Pool
global primes
primes = set()
def log(result):
global primes
if result:
# since the result is a batch of primes, we have to use
# update instead of add (or for a list, extend instead of append)
primes.update(result)
def isPrime( n ):
if n < 2:
return False
if n == 2:
return True, n
max = int(math.ceil(math.sqrt(n)))
i = 2
while i <= max:
if n % i == 0:
return False
i += 1
return True, n
def isPrimeWorker(start, stop):
"""
find a batch of primes
"""
primes = set()
for i in xrange(start, stop):
if isPrime(i):
primes.add(i)
return primes
def main():
global primes
pool = Pool()
# pick an arbitrary chunk size, this will give us 100 different
# chunks, but another value might be optimal
step = 10000
# use xrange instead of range, we don't actually need a list, just
# the values in that range.
for i in xrange(1000000, 2000000, step):
# call the *worker* function with start and stop values.
pool.apply_async(isPrimeWorker,(i, i+step,), callback = log)
pool.close()
pool.join()
print sum(primes)
return
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2611 次 |
最近记录: |