在设计并行系统的程序时,我有一个关于如何构造并行for循环的一般性问题。
假设我有两个命令,foo1()和foo2(),我想并行执行数组的每个元素。重要的是foo2()根本不执行,直到foo1()操作了每个元素。
第1步:在所有元素上调用foo1()
步骤2:当所有步骤1完成后,在所有元素上调用foo2()
我的假设是,为了确保在foo2()开始之前foo1()在每个元素上完成,我必须将这两个函数放在单独的parfor循环中:
parfor(each element n in array){ //step 1
foo1(n);
}
parfor(each element n in array){ //step 2
foo2(n);
}
然而,这种假设可能是错误的。有可能达到同样的效果:
parfor(each element n in array){
foo1(n); //step 1
foo2(n); //step 2
}
我对第二个实现的担心是,在所有foo1()操作完成之前,各个处理器可能会转到foo2()。
在上面的两个实现中,两者都会达到同样的效果吗?或者我是否正确假设只有第一个有两个独立的parfor循环?
非常感谢您的投入。
答案 0 :(得分:1)
你是对的。第二个实现不确保foo1()在foo2()开始之前在每个元素上完成。
如果核心(或线程)的数量小于n,您可以确定您的需求不会成立。即使核的数量等于或大于n,在所有其他核完成foo1()之前,其中一个核很可能会启动foo2()。
顺便说一下,你可以尝试做类似的事情foo1(n) { write(f, "foo1 begin", n); do_some_math; write(f, "foo1 end", n); }
foo2(n) { write(f, "foo2 begin", n); do_some_math; write(f, "foo2 end", n); }
(“正确”的输出不会保证,但“不正确”的输出会证明实现是“错误的”)。