c++ - MPI_DOUBLE_INT 和 C++ 结构
问题描述
MPI标准使用MPI_X_INT
. _ X = FLOAT, DOUBLE, ...
让我们坚持下去MPI_DOUBLE_INT
。它的正式定义是:
(p. 180)数据类型 MPI_DOUBLE_INT 好像由以下指令序列定义:
block[0] = 1; block[1] = 1; disp[0] = 0; disp[1] = sizeof(double); type[0] = MPI_DOUBLE; type[1] = MPI_INT; MPI_TYPE_CREATE_STRUCT(2, block, disp, type, MPI_DOUBLE_INT);
该定义意味着double
和之间没有填充int
。该标准还断言此类型的总大小应为 16,示例为(forchar
而不是int
):
(p.85) 例 4.1假设
Type = {(double, 0), (char, 8)}
(adouble
在位移 0,然后是 achar
在位移 8)。此外,假设double
s 必须在 8 的倍数的地址处严格对齐。然后,此数据类型的范围为 16(9 舍入为 8 的下一个倍数)。
对应的 C++ 结构是struct DI { double d; int i; };
. 这个答案断言struct
应该打包以避免和之间double
的填充int
。但是打包结构的大小是 12(假设sizeof(int) = 4
),并且不可能使用它们的数组:
constexpr auto count = 2; // >1
DI_packed di[count] = {...};
MPI_Send(di, count, MPI_DOUBLE_INT, ...); // wrong!
是否有struct
与 MPI 定义完全对应并且可以在 MPI 代码中安全且可移植地使用的 C++?似乎唯一有保证的使用方法struct
是使用手动添加的尾部填充来定义打包结构char
。这个对吗?
附带说明一下,在我的机器上,MSVC 和 GCC 都为 unpacked 生成“MPI 兼容”布局struct DI
,因此从实际角度来看,这个问题可能无关紧要,但我不确定。
解决方案
也许您可以使用union来做到这一点?
如果您使用 g++ 编译以下内容并运行
#include <iostream>
using namespace std;
int main()
{
typedef struct {double x; int i;} Tmp;
typedef union {char pad[16]; Tmp dint;} Doubleint;
Doubleint value;
value.dint.x = 3.14;
value.dint.i = 6;
cout << "sizeof(Tmp) = " << sizeof(Tmp) << endl;
cout << "sizeof(Doubleint) = " << sizeof(Doubleint) << endl;
typedef struct {double x; int i;} __attribute__((packed)) Packtmp;
typedef union {char pad[16]; Packtmp dint;} Packdoubleint;
Packdoubleint packvalue;
packvalue.dint.x = 6.12;
packvalue.dint.i = 9;
cout << "sizeof(Packtmp) = " << sizeof(Packtmp) << endl;
cout << "sizeof(Packdoubleint) = " << sizeof(Packdoubleint) << endl;
return 0;
}
你得到
sizeof(Tmp) = 16
sizeof(Doubleint) = 16
sizeof(Packtmp) = 12
sizeof(Packdoubleint) = 16
即联合变量(Doubleint 和 Packdoubleint)总是 16 字节长,即使结构具有不同的大小 - 我已经使用特定于 g++ 的属性强制取消填充 Packtmp。
推荐阅读
- spring-boot - java.lang.OutOfMemoryError:Java 堆空间 Hibernate entityIsPersistent
- facebook-graph-api - Instagram 视频发布时的图形 API 问题 - 媒体上传失败,错误代码为 2207026"
- r - plot_ly:可以为 scatter3D 绘图设置主题吗?
- javascript - 如何在 onSubmit 后使用表单显示内容的时间超过一秒钟
- msp430 - 使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值
- stored-procedures - 如何将程序的使用权限授予广泛的角色组?
- api - QuickBooks online 如何确定 ExpenseAccountRef.value?我是否需要查询一个 ACCOUNT 对象来确定该值?
- laravel - 在 Laravel 中发送密码重置链接返回空数组
- postgresql - Postgres - 向角色组中的现有用户授予权限
- python - 我当前的代码收到一个输入,该输入说明要加起来多少斐波那契数,但在六个测试运行之一中输出是错误的