CUDA-aware MPI

    现在越来越多的高性能并行计算将MPI与GPU结合起来:MPI的将任务并行分发,CUDA进行并行计算。大大提高了并行效率。然而我们知道在GPU上进行计算时常常出现数据重CPU到GPU或从GPU到CPU的拷贝过程,在数据量大的情况下这种拷贝过程往往会花费很多时间。因此英伟达公司实现了一种新的技术:CUDA-aware MPI。改技术实现了GPU缓存的直接访问,这样就很好地避免了在使用MPI+CUDA进行并行计算时数据拷贝花费的大量时间。

CUDA-aware MPI 具体介绍:https://devblogs.nvidia.com/parallelforall/introduction-cuda-aware-mpi/

以下是在搭建的一个环境及测试例子:

环境:Ubuntu 14.04.4系统,CUDA-7.5 ,OpenMPI2.0.0

CUDA环境安装可参考:http://blog.csdn.net/masa_fish/article/details/51882183

OpenMPI2.0.0下载地址:https://www.open-mpi.org/software/ompi/v2.x/

OpenMPI安装:下载OpenMPI2.0.0压缩包后

                        解压:tar zxvf openmpi-2.0.0rc.tar.gz

               进入解压目录:cd openmpi-2.0.0rc

               安装:$./configure --prefix=/usr/local/openmpi --with-cuda=/usr/local/cuda-7.5 

                     $  make

                     $  make install

               添加环境变量:$ vi ~/.bashrc

                             在末尾添加:export PATH="$PATH:/usr/local/openmpi/bin"

                             export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/openmpi/lib/"

                      $sudo ldconfig

测试环境:ompi_info--parsable--all|grep mpi_built_with_cuda_support:value

    输出:         mca:mpi:base:param:mpi_built_with_cuda_support:value:true

测试例子test.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#include <cuda_runtime.h>
int main( int argc, char *argv[] )
{
  int rank,size;
  float *ptrA;
  float *hostptr , *hostptrB;
  int  elements = 32;
  MPI_Status status;
  int i,j;
  clock_t starttime,endtime;
  starttime=clock();
  MPI_Init( &argc, &argv );
  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
  MPI_Comm_size( MPI_COMM_WORLD, &size);
  hostptr=(float*)malloc( elements*sizeof(float) );
  cudaMalloc( (void**)&ptrA, elements * sizeof(float) );
  hostptrB=(float*)malloc( elements *sizeof(float) );
  if( rank == 0 )
  {
     for(i=0;i<elements;i++){
        hostptr[i]=2.0f;
     }
    printf("d====%f\n",hostptr[5]);
    cudaMemcpy(ptrA,hostptr,elements*sizeof(float),cudaMemcpyHostToDevice);
//    ptrA=hostptr;
    MPI_Send( ptrA, elements, MPI_FLOAT, 1, 0, MPI_COMM_WORLD );
  }
  if( rank == 1 )
  {
    MPI_Recv( hostptrB, elements, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &status );
     printf("data==%f\n",hostptrB[5]);
    endtime=clock();
    printf("time===%f\n",(double)(endtime-starttime)/CLOCKS_PER_SEC);
  }
  cudaFree( ptrA );
  free(hostptr);
  free(hostptrB);
  MPI_Finalize();

  return 0;
}
编译命令:mpicxx -I/usr/local/cuda-7.5/include -L/usr/local/cuda-7.5/lib64 test.cpp -o test -lcudart
运行命令:mpirun -np 2 ./test
运行结果:d====2.000000 data==2.000000 time===0.359201 

参考文件: https://devblogs.nvidia.com/parallelforall/introduction-cuda-aware-mpi/
            http://mirror.its.dal.ca/openmpi/faq/?category=runcuda#mpi-apis-cuda

               http://bbs.gpuworld.cn/thread-10013-1-1.html

               https://www.olcf.ornl.gov/tutorials/gpudirect-mpich-enabled-cuda/

               http://on-demand.gputechconf.com/gtc-express/2011/videos/GPUDirectandUVA_webinar.mp4

 

       

 

猜你喜欢

转载自985359995.iteye.com/blog/2307341
mpi