使用 MPI 分配不均匀的工作负载
Distributing uneven workload using MPI
我有一个数组
A(1:n_max)
我想用 MPI 对其进行散布以评估一些 f(A(j))。然而,f(A(1)) 的评估需要 0.35 秒,而 f(A(n_max)) 的评估需要 15 秒。我对如何解决它有不同的想法,但我不确定哪个是最好的:
部分Master/Slave工作负载分配。
沿着这条线:http://www.hpc.cam.ac.uk/using-clusters/compiling-and-development/parallel-programming-mpi-example
我用 Reshape(Transpose(Reshape(A)) 对 A 重新排序,这会变成
数组([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17、18、19、20、21、22、23、24、25、26、27、28、29、30、31、32、33、
34、35、36、37、38、39、40、41、42、43、44、45、46、47、48、49、50、
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98])
进入
array([[ 0, 33, 66, 1, 34, 67, 2, 35, 68, 3, 36, 69, 4, 37, 70, 5, 38,
71, 6, 39, 72, 7, 40, 73, 8, 41, 74, 9, 42, 75, 10, 43, 76, 11,
44, 77, 12, 45, 78, 13, 46, 79, 14, 47, 80, 15, 48, 81, 16, 49, 82,
17, 50, 83, 18, 51, 84, 19, 52, 85, 20, 53, 86, 21, 54, 87, 22, 55,
88, 23, 56, 89, 24, 57, 90, 25, 58, 91, 26, 59, 92, 27, 60, 93, 28,
61, 94, 29, 62, 95, 30, 63, 96, 31, 64, 97, 32, 65, 98]])
然后我可以使用分散和收集进行分发。问题是,一个进程必须 运行 f(A(0))、f(A(33)) 和 f(A(66)),而另一个进程必须 运行 f( A(32)、f(A(65)) 和 f(A(98)).
遗憾的是 运行 之间的时间单调上升,但不是线性的。
- 我希望得到你的一些想法
你推荐什么?
如果执行顺序很重要(例如缓存),您可以将数组拆分为大小不同但工作量几乎相等的连续组,然后使用 MPI_SCATTERV
分配它们。
如果数组的末尾很重(在工作负载的情况下),您也可以拆分数组并使用相同的方法两次。
如果执行顺序不重要,并且重新排序不会花费太多时间,我更喜欢第二种方法。
如果你总是有这样的数组,你应该考虑第一个解决方案,但只发送区间限制而不是区间内的所有数字。如果您在通信中受带宽限制,这尤其有意义。
我有一个数组
A(1:n_max)
我想用 MPI 对其进行散布以评估一些 f(A(j))。然而,f(A(1)) 的评估需要 0.35 秒,而 f(A(n_max)) 的评估需要 15 秒。我对如何解决它有不同的想法,但我不确定哪个是最好的:
部分Master/Slave工作负载分配。
沿着这条线:http://www.hpc.cam.ac.uk/using-clusters/compiling-and-development/parallel-programming-mpi-example
我用 Reshape(Transpose(Reshape(A)) 对 A 重新排序,这会变成
数组([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17、18、19、20、21、22、23、24、25、26、27、28、29、30、31、32、33、 34、35、36、37、38、39、40、41、42、43、44、45、46、47、48、49、50、 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98])
进入
array([[ 0, 33, 66, 1, 34, 67, 2, 35, 68, 3, 36, 69, 4, 37, 70, 5, 38,
71, 6, 39, 72, 7, 40, 73, 8, 41, 74, 9, 42, 75, 10, 43, 76, 11,
44, 77, 12, 45, 78, 13, 46, 79, 14, 47, 80, 15, 48, 81, 16, 49, 82,
17, 50, 83, 18, 51, 84, 19, 52, 85, 20, 53, 86, 21, 54, 87, 22, 55,
88, 23, 56, 89, 24, 57, 90, 25, 58, 91, 26, 59, 92, 27, 60, 93, 28,
61, 94, 29, 62, 95, 30, 63, 96, 31, 64, 97, 32, 65, 98]])
然后我可以使用分散和收集进行分发。问题是,一个进程必须 运行 f(A(0))、f(A(33)) 和 f(A(66)),而另一个进程必须 运行 f( A(32)、f(A(65)) 和 f(A(98)).
遗憾的是 运行 之间的时间单调上升,但不是线性的。
- 我希望得到你的一些想法
你推荐什么?
如果执行顺序很重要(例如缓存),您可以将数组拆分为大小不同但工作量几乎相等的连续组,然后使用 MPI_SCATTERV
分配它们。
如果数组的末尾很重(在工作负载的情况下),您也可以拆分数组并使用相同的方法两次。
如果执行顺序不重要,并且重新排序不会花费太多时间,我更喜欢第二种方法。
如果你总是有这样的数组,你应该考虑第一个解决方案,但只发送区间限制而不是区间内的所有数字。如果您在通信中受带宽限制,这尤其有意义。