我首先要声明,我不知道我对MPI缓冲区的假设或理解是否正确。如果不正确,则此问题很可能无效。我已经进行了必要的研究,我认为我的假设是合乎逻辑的。
请注意:下面有一个TL; DR。
假设: 这些是我对MPI Isends的理解:
定义:开始无阻塞发送
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
背景:
我正在为一款名为Othello的游戏编写游戏AI。我正在使用不同的方法,但是在这里,我将重点介绍使用一种称为NegaScout(AlphaBeta / Minimax的变体)的技术。
我专门尝试随着过程数量的增加来提高效率。因此,我希望我的程序具有很高的可扩展性,并且实际上不关心少于8个内核的程序的性能。
我需要一种有效地平衡这些流程的负载的方法。 负载平衡的第一阶段相对容易。只需深入到有足够的树木供每个过程探索的深度即可。当一个进程在另一个之前完成搜索其树时,就会存在问题-负载平衡必须继续。这意味着我们必须在NegaScout算法内部实现负载平衡。
我首先使用主/从(或客户机/服务器)方法来处理动态负载平衡。但是,当流程必须彼此协作时,事情就变得棘手了。我不仅要处理一堆可用的工作,因为alpha beta值取决于每个递归调用中的值,或者取决于它们在树中的状态(板状态)。
我的理论是,如果使用阻塞发送,则可能会产生极大的通信开销。例如,如果我是一个必须将工作发送到请求流程的流程,则使用普通的阻塞发送效率低下,而普通的阻塞发送必须等待另一个可能正在探查其他通信标签的流程;例如TERMINATE_TAG。
我认为最重要的通信开销情况将出现在这里:
MPI_DOUBLE
发送仅分配了一次的缓冲区。但是,现在我等待过程P1收到该消息,然后才能继续寻找工作。现在,过程P1可能处于其树的不同深度。这意味着它不能从P0接收答案,因为我们不能在该深度使用它。现在,P0被阻塞,直到P1返回到该深度。此外,这种情况可能会在多个深度发生多次,从而导致许多进程被阻塞。MPI_Isend
。然后将该缓冲区的地址添加到我的缓冲区链接列表中,以在终止时解除分配。现在,答案是通过非阻塞发送发送的,我可以立即开始寻找更多工作,而不必等待P1处的接收。这是工作量过大的过程的观点:
MPI_Iprobe
探测传入消息。I_MAY_HAVE_WORK_LATER
-视情况而定。非阻塞发送使我可以继续进行其他工作并处理其他传入通信,而不会造成瓶颈。 I_DONT_HAVE_WORK
现在我们有了一些背景,我终于可以问我一个问题:
假设我提出的动态缓冲策略有效,那么有效吗?在不断分配内存中进行权衡是否值得减少通信开销?
这种方法有一个明显的局限性。大量的缓冲区链接列表让我们假设我们有足够的内存来处理此问题。
很长的问题很抱歉。我只是想找到一种在所有流程中平衡负载的有效方法。
TL; DR:
我仍在尝试修复我的代码,因此我自己无法回答这些问题。我希望有更多经验的人可能会指出这种方法是否可行,从而节省一些时间。
非常感谢您阅读这个较长的问题! 任何建议将不胜感激。