MPI之数据类型

来源:互联网 发布:软件汉化教程 编辑:程序博客网 时间:2024/05/16 09:06

我们知道,比较基本的MPI点对点通信具有无法同时发送不同数据类型(当然前面提到了可以使用MPI_PACKED,但是这样会造成性能的极大损耗),因此MPI提供说明更通用的,混合的非连续通信缓冲区的机制.直到执行(implementation)时再决定数据应该在发送之前打包到连续缓冲中,还是直接从数据存储区收集。

这里提供的通用机制允许不需拷贝,而是直接传送各种形式和大小的目标.我们并没有假设MPI库是用本地语言描述的连续目标.因此,如果用户想要传送一个结构或一个数组部分,则需要向MPI提供一个通信缓冲区的定义,该定义用问题模仿那个结构和数组部分的定义.这些工具可以用于使库设计者定义能够传送用本地语言定义的目标的通信函数:通过对可获得的符号表或虚拟向量(dope vector)的定义解码即可. 这种高级通信功能不是MPI的部分。

一个通用的数据类型是一个模糊的目标,它说明两件事情:
一个基本数据类型序列;
一个整数(字节)偏移(displacements)序列

该偏移不要求是整数,互相不同,升序等.因此,各项的顺序可以和存储的顺序不一致,并且同样的项可以出现多次.这样的序列我们称之为”类型映像”(type map).
基本类型序列(忽略偏移)是该数路类型的“类型鉴字”(type signature).

typemap={(type0,disp0),…,(typen-1,dispn-1)}, 是这样的类型映射, 其typei是基本类型, dispi是偏移

typesig={type,…,typen-1} 是相关的类型签字. 这个类型映射和一个基地址buf共同说明一个通信缓冲区:该通信缓冲区包含n个项, 第 i 项在地址buf+dispi处,类型为typei. 一个从该通信缓冲区集成的消息将含有n个值,其类型由typesig定义

一个通用数据类型的偏移量是相对一些初始缓冲区地址的,这些偏移的绝对地址可以被替换掉:我们可以把它看作是零地址的相对偏移量.这个初始零地址是由常量MPI_BOTTOM指明的.这样,一个数据类型可以说明通信缓冲区内元素的绝对地址,这时buf参数传递的是MPI_BOTTOM的值(一个位置在内存中的地址可以通过调用MPI_Address获得)
生成一个可连续的数据类型最简单的方法就是使用MPI_Type_contiguous(),允许把一个数据类型复制到连续的位置
newtype的大小是count*oldtype,内容是连接count个oldtype,其中连接处的大小为为extend.下面为extend的定义:
数据类型的扩充(extent)被定义为该数据类型获得的入口项中从第一个类型到最后一个类型间的距离,循环满足分配的要求. 即如果
typemap={(type0,disp0),…,(typen-1,disp n-1)},

lb(typemap)=min dispJ,
j
ub(typemap)=max(dispJ+sizeof(typeJ)),
j
extent(typemap)=ub(typemap)-lb(typemap)+e (3.1)
如果typei 要求分配ki倍数的字节地址, 则e是使extent(typemap)进入(rount)下一个maxiki所需要的最小非负增长

其实,还有一种更通用的方法:就是使用MPI_Type_vector,允许复制一个数据类型到含有相等大小块的空间.每个块通过连接相同数量的旧数据类型的拷贝来获得.块与块之间的空间是旧数据类型的extent的倍数.
另外还有一个MPI_Type_vector的异构版本:MPI_Type_hvector.

MPI_Type_struct是最通用的类型生成器,它能够在上面介绍的基础上进一步允许每个块包含不同数据类型的拷贝。
MPI_Type_indexed允许复制一个旧数据类型到一个块序列中(每个块是旧数据类型的一个连接),每个块可以包含不同的拷贝数目和具有不同的偏移.所有的块偏移都是旧数据类型extent的倍数
MPI_Type_hindexed是MPI_Type_indexed的相应异构版本。

关于commit和free:
通信中的数据类型(自定义的)必须被commit。可以使用一个计数来记录其使用情况,当必要时可以选择释放它。

原创粉丝点击