1.4 数据类型
MPI的特性之一是所有的通信函数都带一个数据类型参数。数据类型用于描述发送和接收数据的类型,取代老式系统中仅用字节进行描述。例如,如果传输一组整数数据,MPI函数的数据类型在C语言中应该设置为MPI_INT或者在Fortran语言中设置为MPI_INTEGER。使用数据类型参数的目的是在异构环境中,例如在具有不同字节存储顺序或者不同基本数据类型长度的异构计算机系统上,保证通信顺利进行。当数据类型被指定后,MPI能够在内部转换成相应的字节数。MPI支持C99和Fortran 2008中的所有数据类型。
使用数据类型参数的另一个目的是使用户能够描述内存中非连续存放的数据并通过一个单独的MPI函数调用实现数据传输。MPI提供多种数据类型构造函数,可用来描述内存中非连续存放的数据。通过数据类型构造函数描述内存中非连续存放的数据并进行传输,若采用高质量的MPI实现方法,性能将优于先对数据进行打包和解包再传输的通信方式或者先将非连续数据转成连续数据再传输的通信方式。
MPI的数据类型能够描述内存中的各种数据。MPI中预定义的数据类型类似于编程语言中基本的数据类型,例如MPI_FLOAT(等同C语言中float)或者MPI_COMPLEX(等同Fortran语言中COMPLEX)。新的数据类型可由旧的数据类型通过不同的布局进行构造,如下例所示。
新的数据类型有count个数据块,每个数据块中有blocklength个连续的oldtype类型的数据,每个数据块的长度为stride。通过新的数据类型,能够方便和高效地描述间隔规则的非连续数据(一种高效的MPI实现方法可参考文献[139])。
MPI还提供其他更通用的数据构造函数。MPI_Type_indexed比MPI_Type_vector的使用范围更广,可用来定义每个数据块中有不同数量的oldtype类型和偏移量的数据。MPI_Type_create_struct的使用范围最广,还可定义每个数据块中不同数据类型的数据。MPI提供定义数据子数组和分布式数组的函数,这些函数在并行文件I/O中应用广泛。MPI提供的数据构造函数能够递归调用并可描述任何数据类型。
图1-3是采用C语言实现发送二维数组中一列数据的程序示例。因为C语言默认按行优先存储数组,所以发送的该列数据并非连续数据。通过使用向量数据类型定义内存结构,使用一个MPI发送函数便可发送整列数据。在使用派生数据类型前,必须使用MPI_Type_commit函数进行声明。MPI_Type_commit函数会对新构造的数据类型进行分析并在使用新数据类型进行消息通信前对非连续的数据进行通信优化。