我想知道当传输的数据量大致相同时,执行MPI_Alltoallv
和MPI_Alltoall
函数之间的运行时间有何不同?我找不到任何这样的基准测试结果。我对大规模实例感兴趣,其中使用了数万或更好的数十万个MPI过程,并且这些过程对应于给定HPC系统的重要部分(至多考虑一些现代的,例如BG / Q) ,Cray XC30,Cray XE6,......)。
答案 0 :(得分:2)
MPI_Alltoall的一大优势是协议决策可以快速完成,因为它们依赖于少数标量。相反,如果库实现者想要优化MPI_Alltoallv,他们必须扫描四个向量以确定,例如,通信是否几乎是同质的,高度稀疏的,还是其他模式。
另一个问题是MPI_Alltoall可以轻松地将输出缓冲区用作临时空间,因为每个进程都提供并消耗相同数量的数据。对于MPI_Alltoallv,执行所有簿记都不实际,因此将分配任何暂存空间。我无法记住这个问题的细节,但我想我已经在MPI正典的某个地方读到了它。
至少有两个alltoallv的特例,其中一个可以比MPI库更好地优化:
几乎同质的通信,即计数向量几乎是恒定的。当您的分布式阵列不能在整个过程网格中均匀分配时,就会发生这种情况。在这种情况下,您可以:
填充数组并直接使用MPI_Alltoall。
将MPI_Alltoall用于具有同类通信的进程子集,其余为MPI_Alltoallv或一批Send-Recv。如果您可以缓存关联的通信器,这最有效。使用非阻塞通信也应该有所帮助。
编写自己的Bruck实现,处理计数变化的情况,这可能在向量的末尾。我自己没有这样做,我不知道这个是多么困难或有价值。
稀疏通信,即计数向量包含大量零。对于这种情况,只需使用一批非阻塞Send-Recv和Waitall,因为这可能是MPI库最好的,并且自己动手做可以让你根据需要调整批量大小。
MPI on a Million Processors描述了与向量集合相关的可扩展性问题。当然,您可能看不到在大多数CPU上扫描矢量参数的成本,但它是一个O(n)问题,它促使实施者不要过多地触摸矢量参数。
HykSort: a new variant of hypercube quicksort on distributed memory architectures描述了一种比优化库执行得更好的自定义实现。这种优化很难在MPI库中实现,因为它可能相当专业。 (顺便说一下,这个参考文献的目标是Hristo的评论,而不是你的问题。)
通过比较MPICH(https://github.com/pmodels/mpich/blob/master/src/mpi/coll/alltoall.c和https://github.com/pmodels/mpich/blob/master/src/mpi/coll/alltoallv.c)中这些操作的实现,您可以发现一些有趣的事情。只有MPI_Alltoall使用Bruck's algorithm和成对交换。可以从I_MPI_ADJUST_ALLTOALL
上的I_MPI_ADJUST_ALLTOALLV
和$ python3
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 08:49:46)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print('My','name','is','doug')
My name is doug
>>> print('My'+'name'+'is'+'doug')
Mynameisdoug
的可用选项中得出类似的结论。这些限制是基本的还是仅仅是实用的,留给读者练习。
当Blue Gene / P上的MPI_Alltoall使用DCMF_Alltoallv(https://software.intel.com/en-us/node/528906)时,因此相对于MPI_Alltoallv没有差别,后者可能甚至更好,因为应用程序预先填充了矢量参数。
我为Blue Gene / Q编写了一个全面的交换版本,速度和MPI_Alltoall一样快。我的版本与常量与矢量参数无关,因此这个结果意味着MPI_Alltoallv的执行方式与MPI_Alltoall类似。但是,我现在无法找到代码以确保细节。
然而,蓝色基因网络相当特殊,特别是w.r.t.总而言之,所以在CPU比网络快得多的系统上胖树或龙网络上的行为将会大不相同。
我建议您编写一个基准测试并在您打算运行应用程序的位置进行测量。一旦掌握了一些数据,就可以更容易地找出可能遗漏的优化内容。