Python:相同的工作负载分为 4 个内核,适用于多处理库,但在使用 mpi4py 时挂起
Python: Same workload divided across 4 cores works with multiprocessing library but hangs when using mpi4py
我正在尝试使用 Python 了解有关多处理的更多信息。到目前为止,我已经使用了 multiprocessing 库和 mpi4py 库,试图解决一个非常简单的问题。添加大量数字。
我使用了以下逻辑,目标是将所有数字相加到 10^8,所以我将这个范围分成 4 个(我笔记本电脑的内核数)相等的范围,将负载分配给所有内核,然后将结果加到一个核心上。
这是我目前使用的两种不同方法。
使用多处理库:
import multiprocessing
from multiprocessing import Pool
from time import time
def sum_nums(low, high):
result = 0
for i in xrange(low, high+1):
result += i
return result
def sn((low,high)):
return sum_nums(low, high)
if __name__ == '__main__':
p = Pool(4)
n = int(1e8)
r = range(0,10**8+1,n)
results = []
t = time()
for arg in zip([x+1 for x in r],r[1:]):
results.append(p.apply_async(sum_nums, arg))
# wait for results
print sum(res.get() for res in results)
print '{} s'.format(time() -t)
使用 mpi4py 库:
from mpi4py import MPI
import numpy as np
import time
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
end = 10**9
step = round((end+1)/size)
limits = np.linspace(start=0, stop=end,num=size+1,
endpoint=True, dtype=int)
space = []
for arg in zip([x+1 for x in limits],limits[1:]):
space.append(arg)
else:
space = None
data = comm.scatter(space, root=0)
start = time.time()
res = np.sum(np.arange(start=data[0], stop=data[1]+1))
timeDiff = time.time() - start
results = comm.gather(res, root=0)
totalTime = comm.gather(timeDiff, root=0)
if rank == 0:
end = time.time()
print(sum(results))
print("Average computing time: {:.3f}s".format(sum(totalTime)/size))
问题是,虽然 mpi4py 库运行得更快,但尝试计算总和达到 10^7 需要将近 1 秒,而使用第一个代码则需要 4 秒。尝试求解时对于 10^8,第二个代码挂起,而第一个代码在大约 15 秒内给出结果。
为什么会这样?这是内存问题吗?我在第二个代码中完全错了吗?
第一个代码写在python 2.7.15,第二个代码写在python 3.6.7。
感谢您抽出宝贵时间阅读本文,欢迎任何答案!
我认为这是内存问题。
我在 python 3.6.7 环境中尝试了第二个代码。当 end<=10^9 时,代码可以在我的电脑上运行。我的电脑需要超过 40GB 的内存,最终达到 10^10。
我正在尝试使用 Python 了解有关多处理的更多信息。到目前为止,我已经使用了 multiprocessing 库和 mpi4py 库,试图解决一个非常简单的问题。添加大量数字。
我使用了以下逻辑,目标是将所有数字相加到 10^8,所以我将这个范围分成 4 个(我笔记本电脑的内核数)相等的范围,将负载分配给所有内核,然后将结果加到一个核心上。
这是我目前使用的两种不同方法。
使用多处理库:
import multiprocessing
from multiprocessing import Pool
from time import time
def sum_nums(low, high):
result = 0
for i in xrange(low, high+1):
result += i
return result
def sn((low,high)):
return sum_nums(low, high)
if __name__ == '__main__':
p = Pool(4)
n = int(1e8)
r = range(0,10**8+1,n)
results = []
t = time()
for arg in zip([x+1 for x in r],r[1:]):
results.append(p.apply_async(sum_nums, arg))
# wait for results
print sum(res.get() for res in results)
print '{} s'.format(time() -t)
使用 mpi4py 库:
from mpi4py import MPI
import numpy as np
import time
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
end = 10**9
step = round((end+1)/size)
limits = np.linspace(start=0, stop=end,num=size+1,
endpoint=True, dtype=int)
space = []
for arg in zip([x+1 for x in limits],limits[1:]):
space.append(arg)
else:
space = None
data = comm.scatter(space, root=0)
start = time.time()
res = np.sum(np.arange(start=data[0], stop=data[1]+1))
timeDiff = time.time() - start
results = comm.gather(res, root=0)
totalTime = comm.gather(timeDiff, root=0)
if rank == 0:
end = time.time()
print(sum(results))
print("Average computing time: {:.3f}s".format(sum(totalTime)/size))
问题是,虽然 mpi4py 库运行得更快,但尝试计算总和达到 10^7 需要将近 1 秒,而使用第一个代码则需要 4 秒。尝试求解时对于 10^8,第二个代码挂起,而第一个代码在大约 15 秒内给出结果。
为什么会这样?这是内存问题吗?我在第二个代码中完全错了吗?
第一个代码写在python 2.7.15,第二个代码写在python 3.6.7。
感谢您抽出宝贵时间阅读本文,欢迎任何答案!
我认为这是内存问题。 我在 python 3.6.7 环境中尝试了第二个代码。当 end<=10^9 时,代码可以在我的电脑上运行。我的电脑需要超过 40GB 的内存,最终达到 10^10。