1

已编辑:感谢您之前的帮助。对此,我真的非常感激。

我也应该从 *list 中删除指针吗?为了创建 atributo 和 estrucura 我也在使用指针,这也会有问题吗?

union atributo{
    int valor1;
    char valor2[tamChar];  
float valor3;
};


struct estructura{
int tipo[tamEstruct]; //Here i will have an array with the types of the union 
union atributo *list[tamEstruct];

};

union atributo *atributos;  
struct estructura *estructuras;

estructuras = malloc (sizeof(struct estructura) * (cantEstruct) );



MPI_Datatype atributo_MPI;
MPI_Datatype type[1] = { MPI_BYTE };
int blocklen[1] = { tamChar };   // the largest element is the chat
MPI_Aint disp[1];

disp[0]= atributos[0];   // the begin of the union



MPI_Datatype estructura_MPI;
MPI_Datatype type[2] = { MPI_INT, atributo_MPI };
int blocklen[2] = { tamEstruct, tamEstruct};
MPI_Aint disp2[2];

disp2[0]= offsetof(atributos, tipo);
disp2[1]= offsetof(atributos, list);

我正在接近正确的代码吗?

4

1 回答 1

1

那段代码有几处错误。

首先,结构和联合在这种情况下非常不同。结构包含列出的每个元素,在内存中一个接一个地排列。另一方面,联合仅与其最大元素一样大,并且其所有成员共享相同的内存空间(就好像它们是结构的唯一成员一样)。这意味着您不能将联合打包到 中MPI_Struct,因为每个成员的偏移量实际上都是 0。

有两种方法可以解决联合数组的问题:

  • 将它们作为MPI_BYTE. 这很简单,但如果您的进程不共享相同的数据表示形式(例如,它们的整数在字节序上不同),则存在数据损坏的风险。
  • 用于MPI_Pack()将值一一打包。这是类型安全的,但更复杂,它会导致数据的内存副本。

请注意,在任何一种情况下,接收进程都需要知道它接收到的值(即,如果它接收到 3 个联合,那是这 3 个整数,还是 2 个整数和一个浮点数等)。如果您使用工会,您也必须发送此信息。

您可能需要考虑一种更复杂的方法:根据枚举值中的哪个值对枚举进行分组,然后发送一条消息,其中相似的枚举彼此相邻放置(例如,一条消息包含一个MPI_INTs 数组,然后是一个MPI_FLOATs 等)。通过巧妙地使用派生的 MPI 数据类型,您可以保持类型安全、避免内存中复制避免发送多个消息。


第二:永远不要在 MPI 进程之间发送指针!很容易将 achar*视为 s 的数组char,但实际上并非如此。它只是一个内存地址,对您将其发送到的进程没有意义,即使它确实如此,您实际上也没有发送它指向的数据。如果valor2是一个具有相当短的最大长度的字符串,我建议将其声明为char valor2[maxLength]以便在实际的结构/联合内部分配它的内存。如果这不可行,您将不得不做更多的内存杂耍来将您的字符串传递到其他进程,就像使用任何可变大小的数组一样。

于 2013-10-28T18:05:06.260 回答