我有一个非常简单的代码,一个数据分解问题,在一个循环中,每个进程在每个循环中在其自身之前和之后发送两个大消息到级别。我在一个SMP节点集群中运行这段代码(AMD Magny核心,每个节点32个核心,每个插槽8个核心)。有一段时间我正在优化这段代码。我已经使用了pgprof和tau进行分析,在我看来,瓶颈是通信。我试图在我的代码中将通信与计算重叠,但看起来实际的通信是在计算完成时开始的:(
我在就绪模式(MPI_Rsend_init)中使用持久通信,并且在MPI_Start_all和MPI_Wait_all之间完成大部分计算。代码如下所示:
void main(int argc, char *argv[])
{
some definitions;
some initializations;
MPI_Init(&argc, &argv);
MPI_Rsend_init( channel to the rank before );
MPI_Rsend_init( channel to the rank after );
MPI_Recv_init( channel to the rank before );
MPI_Recv_init( channel to the rank after );
for (timestep=0; temstep<Time; timestep++)
{
prepare data for send;
MPI_Start_all();
do computations;
MPI_Wait_all();
do work on the received data;
}
MPI_Finalize();
}不幸的是,直到计算完成,实际的数据传输才开始,我不明白为什么。该网络使用QDR、InfiniBand互连和mvapich2。每条消息大小为23MB (共发送46MB消息)。由于系统中的内存足够大,我尝试将消息传递更改为急切模式。我在作业脚本中使用了以下标志: MV2_SMP_EAGERSIZE=46M
MV2\_CPU\_BINDING\_LEVEL=socket MV2\_CPU\_BINDING\_POLICY=bunch 这给我带来了大约8%的改进,可能是因为在SMP节点内更好地放置了等级,但是仍然存在通信问题。我的问题是,为什么我不能有效地将通信与计算重叠?有没有我应该使用的标志,但是我错过了它?我知道有些地方不对劲,但我所做的一切还不够。
根据SMP节点内部的等级顺序,节点之间的实际消息大小也是46MB (2x23MB),并且等级处于循环中。你能帮帮我吗?为了查看其他用户使用的标志,我检查了/etc/mvolich2.conf,但是它是空的。
有没有其他我应该使用的方法?你认为单边交流能带来更好的表现吗?我觉得有一面旗子或什么东西我没有意识到。
非常感谢。
发布于 2012-12-20 21:00:40
在MPI中有一种叫做操作级数的东西。该标准允许非阻塞操作仅在进行了适当的测试/等待调用后才能进行到完成:
非阻塞send start调用将启动发送操作,但不会完成该操作。在消息被复制出发送缓冲区之前,发送开始调用可以返回。需要单独的send complete调用来完成通信,即验证数据是否已从发送缓冲区复制出来。利用适当的硬件,从发送器存储器传出数据可以与发送器在发起发送之后和完成之前在发送器处完成的计算同时进行。类似地,非阻塞接收开始调用将启动接收操作,但不会完成该操作。该调用可以在消息存储到接收缓冲区之前返回。需要一个单独的接收完成调用来完成接收操作,并验证数据是否已被接收到接收缓冲区。利用适当的硬件,将数据传送到接收器存储器中可以与在启动接收之后并且在接收完成之前进行的计算同时进行。
(粗体中的单词在标准文本中也是粗体的;由我补充强调)
虽然本文来自关于非阻塞通信的部分(MPI-3.0的§3.7;在MPI-2.2中的文本完全相同),但它也适用于持久通信请求。
我没有使用过MVAPICH2,但我可以谈谈在Open MPI中是如何实现的。无论何时启动非阻塞操作或启动持久通信请求,操作都会被添加到挂起操作的队列中,然后以两种可能的方式之一进行:
默认行为是不启用异步进程线程,因为这样做会以某种方式增加操作的延迟。
MVAPICH站点目前无法从这里访问,但之前我在功能列表中看到了异步进度。也许这就是你应该开始的地方--寻找启用它的方法。
还要注意的是,MV2_SMP_EAGERSIZE控制共享存储器协议eager消息大小,并且不影响InfiniBand协议,即它只能改善驻留在同一群集节点上的进程之间的通信。
顺便说一句,不能保证接收操作将在相邻队列中的就绪发送操作之前开始,因此它们可能不会如预期的那样工作,因为在那里时间排序非常重要。
发布于 2015-11-07 10:42:13
对于MPICH,您可以在运行mpiexec/mpirun时设置MPICH_ASYNC_PROGRESS=1环境变量。这将产生一个执行“异步进程”的后台进程。
MPICH_ASYNC_PROGRESS -启动一个空闲线程以提供异步进程。这改进了所有MPI操作的进程语义,包括点对点、集合、单边操作和I/O。设置此变量会将线程安全级别提高到MPI_THREAD_MULTIPLE。虽然这改进了进度语义,但它可能会导致常规MPI操作的少量性能开销。
我已经在我的集群上使用MPICH-3.1.4进行了测试,它工作了!我相信MVAPICH也会工作。
https://stackoverflow.com/questions/13963808
复制相似问题