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 であるため、union を にパックできないことを意味します。

共用体の配列の問題に取り組むには、次の 2 つの方法があります。

  • の配列として送信しますMPI_BYTE。これは単純ですが、プロセスが同じデータ表現を共有していない場合 (たとえば、整数のエンディアンが異なる場合)、データが破損する危険があります。
  • MPI_Pack()値を 1 つずつパックするために使用します。これはタイプ セーフですが、より複雑であり、データのメモリ内コピーが作成されます。

いずれの場合も、受信プロセスは、受信した値を知る必要があることに注意してください (つまり、3 つの共用体を受信した場合、それらの 3 つの整数、または 2 つの整数と浮動小数など)。ユニオンを使用する場合は、この情報も送信する必要があります。

よりトリッキーなアプローチを検討することをお勧めします: どの値が有効であるかに従って列挙型をグループ化し、同様の列挙型が隣り合わせに配置されたメッセージを送信します (たとえば、MPI_INTs の配列を含み、次に の配列を含むメッセージ)。MPI_FLOATなど)。派生 MPI データ型を巧みに使用することで、型の安全性を維持し、メモリ内コピー回避し、複数のメッセージを送信することを回避できます。


2 番目: MPI プロセス間でポインターを送信しないでください。char*aを s の配列と考えるのは簡単ですcharが、実際にはそうではありません。これは、送信先のプロセスにとって意味をなさない単なるメモリアドレスであり、たとえそうであったとしても、それが指しているデータを実際に送信したわけではありません。valor2が合理的に短い最大長の文字列の場合char valor2[maxLength]、そのメモリが実際の構造体/共用体内に割り当てられるように宣言することをお勧めします。それが不可能な場合は、可変サイズの配列の場合と同様に、文字列を他のプロセスに渡すために、さらに多くのメモリ ジャグリングを行う必要があります。

于 2013-10-28T18:05:06.260 に答える