【发布时间】:2011-07-17 08:05:32
【问题描述】:
我测试了将第一个 N 整数相加的(几乎)“令人尴尬的并行”(即完全可并行化)算法并行化的性能增益:
串行算法很简单:
N = 100000000
print sum(range(N))
在我的双核笔记本电脑 (Lenovo X200) 上的执行时间:0m21.111s。
并行化(使用 mpi4py)版本使用 3 个节点;节点 0 计算整数下半部分的总和,节点 1 计算上半部分的总和。两者都将结果(通过comm.send)发送到节点 2,节点 2 将两个数字相加并打印结果:
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
N = 100000000
if rank == 0:
s = sum(range(N/2))
comm.send(s,dest=2,tag=11)
elif rank == 1:
s = sum(range(N/2+1,N))
comm.send(s,dest=2,tag=11)
elif rank == 2:
s1 = comm.recv(source=0, tag=11)
s2 = comm.recv(source=1, tag=11)
print s1+s2
我的双核笔记本的两个核心都用完了;现在执行时间:15.746s。
我的问题:至少在理论上,执行时间应该接近一半。哪个开销吃掉了丢失的 4 秒? (当然不是 s1+s2)。那些发送/接收命令那么耗时吗??
编辑:在阅读答案并重新思考问题后,我认为 4 秒(在某些运行中甚至超过)被生成两个列表导致的高内存流量吃掉了长度 50000000;我的笔记本电脑的两个内核共享一个公共内存(至少是主内存;我认为它们有单独的 L2 缓存),这正是瓶颈:所以,很多时候,两个内核都想同时访问内存(为了获取下一个列表元素),其中一个必须等待......
如果我使用xrange 而不是range,则会延迟生成下一个列表元素并且分配的内存很少。
我对其进行了测试,使用 xrange 运行与上述相同的程序只需 11 秒!
【问题讨论】:
-
“执行时间应该差不多减半”?真的吗?为什么?我还没有看到这个理论结果。阿姆达尔定律没有说明这一点。你能提供一些关于这个理论的链接或参考吗?
-
你在什么硬件上?这可能是来自两个内核的并发内存访问降低缓存效率的问题。如果将
range()替换为xrange()会发生什么情况,从而几乎消除了内存访问? -
@Sven Marnach:这是一个很好的建议——我会试试的。
标签: python parallel-processing mpi