你的理解基本正确,除了 indices
应该给出每个结构体字段从开头算起的偏移量(以字节为单位)。 构建这种类型的正确方法是使用在 stddef.h
中定义的 offsetof
运算符:
#include <stddef.h>
struct Residence
{
double x;
double y;
};
MPI_Datatype createRecType()
{
MPI_Datatype new_type;
int count = 2;
int blocklens[] = { 1,1 };
MPI_Aint indices[2];
indices[0] = (MPI_Aint)offsetof(struct Residence, x);
indices[1] = (MPI_Aint)offsetof(struct Residence, y);
MPI_Datatype old_types[] = {MPI_DOUBLE,MPI_DOUBLE};
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
MPI_Type_commit(&new_type);
return new_type;
}
虽然这对于特定的结构来说已经足够了,但是通常情况下,为了考虑编译器可能在结构末尾插入任何尾随填充,我们需要调整结构类型的长度。只有在想要发送多个该结构类型的项,即结构元素数组时才需要这样做。旧的方法是向结构中添加一个第三个成员,类型为MPI_UB
(UB表示上限),并将该成员的偏移量设置为sizeof(struct Residence)
(填充在结构大小中由sizeof
返回)。现代方式是使用MPI_Type_create_resized
,它创建一个具有与原始MPI类型相同类型签名但不同范围的新MPI类型:
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
MPI_Type resized_new_type;
MPI_Type_create_resized(new_type,
indices[0],
(MPI_Aint)sizeof(struct Residence),
&resized_new_type);
MPI_Type_commit(&resized_new_type);
MPI_Type_free(&new_type);
return resized_new_type;
只显示相关的代码行。上面的代码假定
indices [0]
给出第一个结构元素的偏移量。可以使用
MPI_Type_get_extent
来获取真正的下限,对于具有负偏移量的结构类型也可以工作。不需要提交
new_type
,因为它仅用于构造调整大小的类型。也没有必要保留它,在创建
resized_new_type
之后释放即可。