function fdtd1d_local(steps, ie = 200)
ez = zeros(ie + 1);
hy = zeros(ie);
for n in 1:steps
for i in 2:ie
ez[i]+= (hy[i] - hy[i-1])
end
ez[1]= sin(n/10)
for i in 1:ie
hy[i]+= (ez[i+1]- ez[i])
end
end
(ez, hy)
end
fdtd1d_local(1);
@time sol1=fdtd1d_local(10);
elapsed time: 3.4292e-5 seconds (4148 bytes allocated)
我天真地尝试过:
function fdtd1d_local_parallel(steps, ie = 200)
ez = dzeros(ie + 1);
hy = dzeros(ie);
for n in 1:steps
for i in 2:ie
localpart(ez)[i]+= (hy[i] - hy[i-1])
end
localpart(ez)[1]= sin(n/10)
for i in 1:ie
localpart(hy)[i]+= (ez[i+1]- ez[i])
end
end
(ez, hy)
end
fdtd1d_local_parallel(1);
@time sol2=fdtd1d_local_parallel(10);
elapsed time: 0.0418593 seconds (3457828 bytes allocated)
sol2==sol1
true
结果是正确的,但性能却差很多。所以为什么?因为并行化不适用于双核旧笔记本电脑,还是我又错了?
好吧,我承认我唯一知道的关于并行化是它可以加速代码,但并不是每一段代码都可以并行,在尝试并行编程之前,有没有什么基本的知识是应该知道的?
任何帮助,将不胜感激。
最佳答案
有几件事情正在发生。首先,注意内存消耗的差异。这是有问题的迹象。通过将分配(您的 zeros
和 dzeros
行)与核心算法分开,您将获得更大的清晰度。然而,大部分内存不太可能被分配使用。更有可能的是,循环中的某些内容正在使用内存。请注意,您正在描述 localpart
在左侧,但您使用的是原始 DArray
在右手侧。这可能会触发一些 IPC 流量。如果需要调试内存消耗,请查看 ProfileView 包。
其次,对我来说,您是否真的在流程之间分解问题并不明显。您正在遍历整个数组的每个元素,而应该让每个工作人员遍历自己的数组部分。但是,您将在 localparts 之间的边缘遇到问题,因为更新需要相邻值。您最好使用 SharedArray
.
最后,启动线程有开销;对于小问题,最好不要并行化,只使用简单的算法。只有当计算时间达到数百毫秒(或更多)时,我才会考虑进行并行化。
关于parallel-processing - 我可以利用并行化来使这段代码更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23290917/