1、15 题每题 20 分1.1)简述 MPI 6 个函数格式定义,作用,参数含义。MPI 简介:消息传递接口的标准,用于开发基于消息传递的并行程序,目的是为用户提供一个实际可用的、可移植的、高效和灵活的消息传递接口库,能够在 PC Windows 和所有主要的 Unix 工作站以及并行机上实现。MPI 是一个库,不是一种语言,实现并行必须依托于某种语言:FORTRAN,MPI 主要函数:MPI_Init,初始化函数:MPI 程序通过调用 MPI_Init 函数进行 MPI 环境,并完成所有的初始化工作,这个函数通常是 MPI 程序的第一个函数调用。格式如下: int MPI_Init( int
2、*argc, char *argv )MPI_Finalize,结束函数:MPI 通过调用 MPI_Finalize 函数从 MPI 环境中退出,它是 MPI程序的最后一个 MPI 函数调用,否则程序的执行结果是不可预知的。格式如下: int MPI_Finalize(void) ;MPI_Comm_rank,获取进程的编号:MPI 程序通过 MPI_Comm_Rank 函数调用获取当前进程在指定通信域中的编号,有了该编号,不同的进程就可以将自身和其他进程区分开来,从而实现进程间的并行和合作。格式如下:nt MPI_Comm_rank(MPI_Comm comm, int *rank)MPI_
3、Comm_size,获取指定通信域的进程数:MPI 通过调用 MPI_Comm_size 函数获取指定通信域的进程个数,进程可根据它来确定自己应该完成的任务比例。格式如下:int MPI_Comm_size(MPI_Comm comm, int *size)MPI_Send 消息发送函数:MPI_Send 函数用于发送一个消息到目标进程。其格式如下:int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm_comm)buf : 消息发送的起始地址count :发送消息的数量dat
4、atype: 发送数据的类型dest: 标识目标进程tag: 发送消息时打上的标签comm: 通信类型MPI_Recv,消息接收:MPI_Recv 函数用于从指定进程接收一个消息,格式如下:int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm, comm, MPI_Status *status )buf : 消息接收后存放地址count : 接收数量datatype : 接收数据类型source : 发送消息的进程tag : 消息的标签comm : 通信类型status
5、: 接收状态1.2)举例简单的应用解释如何通信。每个进程会属于一个或多个通信域。2一个简单的例子/* simple.c */#include “mpi.h” /*MPI 头文件*/#include int main(argc, argv)int argc ;char *argv ;int rank, size, tag = 1 ;int senddata, recvdata ;MPI_Status status ;MPI_Init( /*MPI 的初始化*/MPI_Comm_rank( MPI_COMM_WORLD, /*该进程的编号 */MPI_Comm_size( MPI_COMM_WOR
6、LD, /* 总的进程数目*/if ( rank = 0 )int senddata, recvdata ;MPI_Status status ;MPI_Init( /*MPI 的初始化*/MPI_Comm_rank( MPI_COMM_WORLD, /*该进程的编号 */MPI_Comm_size( MPI_COMM_WORLD, /* 总的进程数目*/if ( rank = 0 )senddata = 9999 ;MPI_Send( /* 发送数据到进程 1 */if ( rank = 1 )MPI_Recv( /*从进程 0 接收数据*/MPI_Finalize() ; /*MPI 的结
7、束函数*/return (0) ;另一个例子实现 sum( a + b ),并且把求和结果打印出来。这里 a, b 都是 n 维空间的向量,并且每个元素都为整数。#include “mpi.h” /*MPI 头文件*/#include #include int main(argc, argv)int argc ;char *argv ;3int rank, size, i, tag = 1 ; int *a, *b, n;n = 100 ;a = (int*)malloc( sizeof( int ) * n ) ;b = (int*)malloc( sizeof( int ) * n ) ;
8、for(i = 0 ; i /*MPI 头文件*/#include #include int main(argc, argv)int argc ;char *argv ;int rank, size, tag = 1 ;int *a, *b , n = 100 ;a = (int*)malloc( sizeof( int ) * n ) ; b = (int*)malloc( sizeof( int ) * n ) ; int i ;for( i = 0 ; i /*MPI 头文件*/#include #include int main(argc, argv)int argc ;char *a
9、rgv ;int rank, size;int n = 100 ;int i ; MPI_Status status ;MPI_Init( MPI_Comm_size( MPI_COMM_WORLD, int nSize = n / size ; MPI_Comm_rank( MPI_COMM_WORLD, int *a, *b ;a = (int*)malloc( sizeof(int) * n ) ;b = (int*)malloc( sizeof(int) * n ) ;int( i = 0 ; i /*MPI 头文件*/#include #include int main(argc,
10、argv)int argc ;char *argv ;int rank, size;int n = 100 ;int i ; MPI_Status status ;MPI_Init( MPI_Comm_size( MPI_COMM_WORLD, int nSize = n / size ; MPI_Comm_rank( MPI_COMM_WORLD, int tag = 1 ; if( rank != (size - 1) )int sum = 0 ;for( i = 0 ; i =0 char *argv ;int rank, size;double *data ;int *indices,
11、 *ptr ; double *b, *x ; data = (double*)malloc( sizeof( double ) * SIZE * 5 ) ;indices = (int*)malloc( sizeof( int ) * SIZE * 5 ) ;ptr = (int*)malloc( sizeof( int ) * (SIZE + 1) ) ; x = (double*)malloc( sizeof( double ) * SIZE ) ;b = (double*)malloc( sizeof( double ) * SIZE ) ;csr_scalar_sparse_matr
12、ix_cpu(data, indices, ptr) ;int i, j, k ;for( k = 0 ; k #include #include #include #define SIZE 1048576#define BLOCK_NUM 32#define THREAD_NUM 256_global_ void sumOfSquares_gpu0( float *a, int n, float *result )int tid = threadIdx.x ;int bid = blockIdx.x ;float sum = 0.0 ;for( int i = bid * THREAD_NU
13、M + tid ; i ( dev_a, SIZE, dev_result ) ;cudaMemcpy(result, dev_result, BLOCK_NUM * THREAD_NUM * sizeof(float), cudaMemcpyDeviceToHost ) ;double sum = 0.0 ;for(int i = 0 ; i #include #include #include 12#define SIZE 1048576#define BLOCK_NUM 32#define THREAD_NUM 256_global_ void sumOfSquares_gpu0( fl
14、oat *a, int n, float *result )_shared_ float sharedTHREAD_NUM;int tid = threadIdx.x ;int bid = blockIdx.x ;sharedtid = 0.0 ;for( int i = bid * THREAD_NUM + tid ; i ( dev_a, SIZE, dev_result ) ;cudaMemcpy(result, dev_result, BLOCK_NUM * sizeof(float), cudaMemcpyDeviceToHost ) ;double sum = 0.0 ;for(i
15、nt i = 0 ; i #include #include #include #define SIZE 1048576#define THREAD_NUM 256_global_ void sumOfSquares_gpu0( float *a, int n, float *result )int tid = threadIdx.x ;float sum = 0.0 ;for( int i = tid ; i ( dev_a, SIZE, dev_result ) ;cudaMemcpy(result, dev_result, THREAD_NUM * sizeof(float), cuda
16、MemcpyDeviceToHost ) ;double sum = 0.0 ;for(int i = 0 ; i #include #include #include #define SIZE 1048576#define BLOCK_NUM 32#define THREAD_NUM 256_global_ void sumOfSquares_gpu0( float *a, int n, float *result )_shared_ float sharedTHREAD_NUM;int tid = threadIdx.x ;int bid = blockIdx.x ;sharedtid =
17、 0.0 ;for( int i = bid * THREAD_NUM + tid ; i ( dev_a, SIZE, dev_result ) ;cudaMemcpy(result, dev_result, BLOCK_NUM * sizeof(float), cudaMemcpyDeviceToHost ) ;double sum = 0.0 ;for(int i = 0 ; i BLOCK_NUM ; i+ )sum += resulti ;cudaEventRecord( stop, 0 ) ;cudaEventSynchronize( stop ) ;cudaEventElapsedTime( printf( “TotalTime = : %20.12f ms n “, elapsedTime ) ;printf( “sum = : %20.12fn “, sum ) ;cudaEventDestroy( start ) ;cudaEventDestroy( stop ) ;free( a ) ;cudaFree( dev_a ) ;cudaFree( dev_result ) ;return 0 ;