如果我不必关心异构系统上的可移植性(endianity ......):
为什么不使用MPI_BYTE进行所有通讯?
特别是对于集体和处理组合数据类型,这将使生活更容易。
编辑:我刚刚找到MPI and C structs。答案适用于我的问题。
答案 0 :(得分:1)
好的,答案是扩展我的讽刺评论:
...出于同样的原因,我们不对所有计算使用字节。在处理现代计算机程序中遇到的那种复杂性时,数据类型是一种巨大的帮助。我引用了这个断言的支持,他们出现在汇编语言层面以上的所有编程语言中,但即使在那个层面上也存在数据类型的痕迹。
MPI最常用的域中的主要语言,即Fortran,C和C ++,具有与MPI中定义的数据类型紧密对应的数据类型。当然,因果关系链在另一个方向起作用,MPI有那些类型,因为那些语言。所有这些语言都允许程序员定义由更基本的数据类型组成的更多数据类型,同样有助于处理解决计算机上难题的复杂性; MPI也支持创建派生类型。
我对你的结论提出异议,即单独处理字节会使(MPI)编程更容易,这会使我的编程更加困难。如果我想从一个进程向另一个进程发送一个包含24个整数的消息,我想发送一个整数和长度为24的消息,我不想摆弄将其转换为多个字节。
答案 1 :(得分:1)
以下是使用类型发送三维NxNxN阵列片段的方法:
double array[N][N][N];
/* ... */
MPI_Datatype xslice, yslice, zslice;
int starts[3] = {0,N-2,0};
int sizes[3] = {N,N,N};
int subsizes[3] = {N,2,N};
MPI_Type_create_subarray(3, sizes, subsizes, starts, MPI_ORDER_C, MPI_DOUBLE, &yslice);
MPI_Type_commit(&yslice);
/* ... */
MPI_Send(&(array[0][0][0]), 1, yslice, neigh, ytag, MPI_COMM_WORLD);
仅使用MPI_BYTE
而不使用其他类型构造函数的方法更简单,更少打字?
高性能计算的所有最终归结为理解内存和数据布局,使用更高级别的抽象有助于此。
如果您遇到MPI_Type_create_struct
问题,那么您来对地方(或其中一个)。如果你来找人同意你的意见,那么学习新东西太难了,不值得,你可能在错误的地方。
编辑添加:。我同意结构化对于序列化来说是一种痛苦 - 不仅仅是MPI - 在C和Fortran中,我责备他们不可原谅的缺乏任何甚至是基本的内省。为了描述它们,你必须重申它们的类型和数量,这违反了DRY原则。这周围一团糟,并且可能有多个代码只使用sizeof(struct foo)MPI_BYTE来描述它们。但这是一个具体的例子,说明失败的地方。
现在您正确地发送和接收这些内容,您决定使用MPI-IO(或者就此而言,HDF5或NetCDF或......)将它们保存到文件中。您使用与传达它们相同的方法来描述它们,当然,也可以是sizeof(struct foo)bytes。
然而,C几乎没有告诉你这些结构是如何布局的;允许编译器对布局执行各种操作,特别是插入填充。如果所有任务都在同一台机器上运行使用相同编译器和标志编译的相同代码,这通常不是通信问题。但是现在当你不可避免地使用相同的代码加载该文件但是使用不同的编译器编译,或者甚至是相同的编译器但是使用不同的标志时,所有的赌注都会被关闭。数据布局可能不同,导致垃圾值 - 或填充量可能不同,导致您读取文件末尾。
您可以通过不同地描述文件I / O和通信的数据来解决这个问题,但现在很难说这会使事情变得更简单。最好只是开始正确描述数据。