Math 用于并行处理的n平方/2分块
我有一个n平方的循环,我想把它分解成几个块来并发运行。循环如下所示:Math 用于并行处理的n平方/2分块,math,parallel-processing,Math,Parallel Processing,我有一个n平方的循环,我想把它分解成几个块来并发运行。循环如下所示: for i = n to m for j = i to m // Do something 0 - 11999 12000 - 23999 24000 - 35999 36000 - 47999 48000 - 60000 for i = 0 to 11999 for j = i to 60000 for i = 12000 to 23999 for j = i to 60000
for i = n to m
for j = i to m
// Do something
0 - 11999
12000 - 23999
24000 - 35999
36000 - 47999
48000 - 60000
for i = 0 to 11999
for j = i to 60000
for i = 12000 to 23999
for j = i to 60000
for i = 24000 to 35999
for j = i to 60000
for i = 36000 to 47999
for j = i to 60000
for i = 48000 to 60000
for j = i to 60000
根据评论进行编辑:
n=0,m=60000的具体示例:
for i = 0 to 60000
for j = i to 60000
所以,我不是真的在做n平方迭代,而是n平方/2。随着我变得越来越大,内部外观中的迭代次数变得越来越少
假设n=0,m=60000,我想把它分成5个独立的进程并行运行。我如何选择n和m,使5个不同的过程具有相同的迭代次数
我知道60000/5=12000。所以,我们可以这样分解它:
for i = n to m
for j = i to m
// Do something
0 - 11999
12000 - 23999
24000 - 35999
36000 - 47999
48000 - 60000
for i = 0 to 11999
for j = i to 60000
for i = 12000 to 23999
for j = i to 60000
for i = 24000 to 35999
for j = i to 60000
for i = 36000 to 47999
for j = i to 60000
for i = 48000 to 60000
for j = i to 60000
其思想是将其分解为x个循环(此处x为5),并进行相同次数的迭代。大概是这样的:
for i = n to m
for j = i to m
// Do something
0 - 11999
12000 - 23999
24000 - 35999
36000 - 47999
48000 - 60000
for i = 0 to 11999
for j = i to 60000
for i = 12000 to 23999
for j = i to 60000
for i = 24000 to 35999
for j = i to 60000
for i = 36000 to 47999
for j = i to 60000
for i = 48000 to 60000
for j = i to 60000
但是,最后的循环比较较少。所以,这不是正确的答案
这似乎是一个微积分问题,你需要计算出曲线下的相等面积。但是,这个数学对我来说已经过时20年了。当然,我在寻找一个给定n=0和m>0的一般解
编辑2:
对上述问题的澄清
感谢以下是我如何用语言编写嵌套循环,例如Fortran或Matlab,它允许指定循环的跨步。我希望这可以翻译成大多数其他编程语言与循环 我假设您的并发程序分布在多个线程(或进程,哪一个并不重要),有一个函数
num_-pids
返回计算中的进程数,还有一个函数my_-pid
,返回范围为0..num_-pids-1
的整数
然后,我会用伪Fortran编写
do i = my_pid, m, num_pids
do j = i, m
....
end do
end do
将三元组
my_-pid,m,num_-pid
解释为以num_-pid的步骤从my_-pid到m的。这不会给出完全平衡的负载,但对于大多数用途来说,平衡应该足够好。以下是我如何用一种语言编写嵌套循环,例如Fortran或Matlab,它允许指定循环的步长。我希望这可以翻译成大多数其他编程语言与循环
我假设您的并发程序分布在多个线程(或进程,哪一个并不重要),有一个函数num_-pids
返回计算中的进程数,还有一个函数my_-pid
,返回范围为0..num_-pids-1
的整数
然后,我会用伪Fortran编写
do i = my_pid, m, num_pids
do j = i, m
....
end do
end do
将三元组my_-pid,m,num_-pid
解释为以num_-pid的步骤从my_-pid到m的。这不会给出完全平衡的负载,但对于大多数目的来说,平衡应该足够好。内部循环中的迭代次数有一个独特的模式,可以利用它来更均匀地分配工作。内循环中的迭代次数随着外循环的每次迭代而减少一次。因此,内循环迭代次数为:
inner
i iterations
--- ----------
0 m
1 m-1
2 m-2
. .
. .
. .
m-2 2
m-1 1
m 0
从该表可以看出,i=0
和i=m
的总内部迭代次数为m
。此外,i=1
和i=m-1
的总内部迭代次数为m
。事实上,对于任何c
而言,i=c
和i=m-c
的总内部迭代次数为m
(外部迭代次数为奇数的情况除外)
根据这一事实,可以在每次外部迭代的基础上分配进程,以便更好地均匀分配负载。只需以蛇形方式将整个内部循环分配给进程。对于5个过程的情况,分配遵循以下模式:
i process
--- --------
0 1
1 2
2 3
3 4
4 5
5 5
6 4
7 3
8 2
9 1
. .
. .
. .
使用这种方法,每个进程将处理大约相同数量的内部循环迭代,特别是对于较大的m
值。内部循环中的迭代次数有一种不同的模式,可以利用该模式更均匀地分配工作。内循环中的迭代次数随着外循环的每次迭代而减少一次。因此,内循环迭代次数为:
inner
i iterations
--- ----------
0 m
1 m-1
2 m-2
. .
. .
. .
m-2 2
m-1 1
m 0
从该表可以看出,i=0
和i=m
的总内部迭代次数为m
。此外,i=1
和i=m-1
的总内部迭代次数为m
。事实上,对于任何c
而言,i=c
和i=m-c
的总内部迭代次数为m
(外部迭代次数为奇数的情况除外)
根据这一事实,可以在每次外部迭代的基础上分配进程,以便更好地均匀分配负载。只需以蛇形方式将整个内部循环分配给进程。对于5个过程的情况,分配遵循以下模式:
i process
--- --------
0 1
1 2
2 3
3 4
4 5
5 5
6 4
7 3
8 2
9 1
. .
. .
. .
使用这种方法,每个进程将进行大约相同数量的内部循环迭代,特别是对于较大的m
值。但是,我认为我最初的问题陈述是正确的,我添加了一个具体的例子。但是,我认为我最初的问题陈述是正确的,那么您会根据进程/线程的数量在外部循环中创建一个步骤吗?明白了。我没有想到这一点。我一直在试图找出开始/结束编号。啊,那么你会根据进程/线程的数量在外部循环中创建一个步骤吗?明白了。我没有想到这一点。我一直在想开始/结束的数字。