如何使用MPI_Send发送嵌套有其他结构体的复合结构体数据
关于st_b类型数据的MPI_Send使用解答
结论
可以发送,但不能直接将st_b变量作为基础类型传入MPI_Send,需要先为嵌套结构体自定义MPI派生数据类型,否则会存在内存对齐导致的兼容性问题。
核心原因
C语言标准允许编译器在结构体成员之间插入填充字节做内存对齐,不同编译配置、不同CPU架构下st_b的内存布局可能存在差异,直接按原始字节发送会出现数据解析错误,也会产生不必要的传输开销。
实现步骤
1. 先为基础结构体st_a定义MPI派生类型
#include <stddef.h> // 用于offsetof宏 // st_a的MPI派生类型定义 int st_a_block_num = 2; int st_a_block_len[] = {1, 1}; MPI_Aint st_a_displ[] = {offsetof(st_a, a), offsetof(st_a, b)}; MPI_Datatype st_a_type_list[] = {MPI_INT, MPI_INT}; MPI_Datatype mpi_st_a; MPI_Type_create_struct(st_a_block_num, st_a_block_len, st_a_displ, st_a_type_list, &mpi_st_a); MPI_Type_commit(&mpi_st_a);
2. 再为嵌套结构体st_b定义MPI派生类型
// st_b的MPI派生类型定义 int st_b_block_num = 2; int st_b_block_len[] = {1, 1}; MPI_Aint st_b_displ[] = {offsetof(st_b, c), offsetof(st_b, d)}; MPI_Datatype st_b_type_list[] = {MPI_DOUBLE, mpi_st_a}; MPI_Datatype mpi_st_b; MPI_Type_create_struct(st_b_block_num, st_b_block_len, st_b_displ, st_b_type_list, &mpi_st_b); MPI_Type_commit(&mpi_st_b);
3. 调用MPI_Send发送数据
st_b send_data; // 给send_data的成员赋值逻辑 MPI_Send(&send_data, 1, mpi_st_b, 目标进程号, 消息标签, MPI_COMM_WORLD);
注意事项
- 派生类型使用完毕后需要调用
MPI_Type_free(&mpi_st_a)和MPI_Type_free(&mpi_st_b)释放资源,避免内存泄漏。 - 仅在同架构、同编译参数的进程间临时测试时,可以用
MPI_Send(&send_data, sizeof(st_b), MPI_CHAR, ...)的写法跑通,但该写法兼容性极差,生产环境严禁使用。
内容的提问来源于stack exchange,提问作者Amesh Fernando
相关产品推荐
相关产品推荐

