gpt4 book ai didi

python 素数处理 : processing pool is slower?

转载 作者:太空狗 更新时间:2023-10-29 20:46:24 27 4
gpt4 key购买 nike

所以最近几天我一直在摆弄 python 的多处理库,我真的很喜欢处理池。它很容易实现,我可以想象出很多用途。我已经完成了几个我以前听说过的项目来熟悉它,最近完成了一个暴力破解刽子手游戏的程序。

任何人,我正在做一个执行时间比较,对单线程和处理池中 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()

它目前将在单个线程中运行,遍历处理池,取消注释池语句并注释掉主 for 循环中的其他行。

最佳答案

使用多处理 的最有效方法是将工作分成 n 个大小相等的 block ,其中 n 是池的大小,这应该大约是系统上的核心数。这样做的原因是启动子进程和它们之间通信的工作量相当大。如果工作的大小与工作 block 的数量相比较小,那么 IPC 的开销就会变得很大。

在你的例子中,你要求 multiprocessing 单独处理每个素数。处理该问题的更好方法是向每个工作人员传递一个值范围(可能只是一个开始值和结束值),并让它返回它找到的该范围内的所有素数。

在识别大素数的情况下,完成的工作随着起始值的增加而增长,因此您可能不想将总范围恰好划分为 n 个 block ,而是 n*k 个相等的 block ,其中 k一些合理的小数字,比如 10 - 100。这样,当一些 worker 比其他 worker 先完成时,还有更多的工作要做,并且可以在所有 worker 之间有效地平衡。

编辑:这是一个改进的示例,用于展示该解决方案的外观。我尽可能少地进行了更改,以便您可以将苹果与苹果进行比较。

#!/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()

关于python 素数处理 : processing pool is slower?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7209657/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com