建筑物
O(N**2)
序列化代码中未使用的3元素dict,并通过进程间管道传输它们,是保证多处理无法帮助的非常好的方法;-)没有免费的东西-一切都要花钱。
下面是一个执行很多
相同的
不管它是在串行还是多处理模式下运行的代码。一般来说,没有新的口述等
len(coords)
,它从多处理中获得的好处越多。在我的盒子里,20000次的多处理运行需要大约三分之一的挂钟时间。
关键是所有进程都有自己的
coords
. 这是通过在创建池时只传输一次来完成的。这应该在所有平台上都有效。在Linux-Y系统上,它可以通过“魔术”而不是分叉进程继承来实现。减少跨进程发送的数据量
o(n×2)
到
O(N)
是一个巨大的进步。
从多处理中获得更多信息需要更好的负载平衡。按原样,打电话给
check_overlap(i)
比较
coords[i]
中的每个值
coords[i+1:]
. 较大的
i
,它要做的工作越少,最大值为
我
只是传输的成本
我
在进程之间-并将结果传输回-占用了大量的时间
在里面
检查重叠(I)
.
def init(*args):
global _coords, _tolerance
_coords, _tolerance = args
def check_overlap(start_index):
coords, tolerance = _coords, _tolerance
tsq = tolerance ** 2
overlaps = 0
start0, start1 = coords[start_index]
for i in range(start_index + 1, len(coords)):
that0, that1 = coords[i]
dx = abs(that0 - start0)
if dx <= tolerance:
dy = abs(that1 - start1)
if dy <= tolerance:
if dx**2 + dy**2 <= tsq:
overlaps += 1
return overlaps
def process_coords(coords, num_processors=1, tolerance=1):
global _coords, _tolerance
import multiprocessing as mp
_coords, _tolerance = coords, tolerance
import time
if num_processors > 1:
pool = mp.Pool(num_processors, initializer=init, initargs=(coords, tolerance))
start = time.time()
print("Start script w/ multiprocessing")
else:
num_processors = 0
start = time.time()
print("Start script w/ standard processing")
N = len(coords)
if num_processors:
total_overlap_count = sum(pool.imap_unordered(check_overlap, range(N)))
else:
total_overlap_count = sum(check_overlap(i) for i in range(N))
print(total_overlap_count)
print(" time: {0}".format(time.time() - start))
if __name__ == "__main__":
from random import random
coords = []
num_coords = 20000
spread = 100.0
half_spread = 0.5*spread
for i in range(num_coords):
coords.append([
random()*spread-half_spread,
random()*spread-half_spread
])
process_coords(coords, 1)
process_coords(coords, 4)