简体   繁体   English

MPI_File_write_at:两次写入相同的结构会导致二进制文件中的数据块略有不同

[英]MPI_File_write_at : Writing the same struct twice results in slightly different data blocks in binary file

I have the following simple MPI code:我有以下简单的 MPI 代码:

#include <iostream>
#include <mpi.h>

int main() {
    struct test {
        int rank = 1;
        double begin = 0.5;
        double end = 0.5;
    };

    MPI_Init(NULL, NULL);
    
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    MPI_File fh;
    MPI_Offset offset;
    MPI_Status status;
    MPI_Datatype TIMEDATA_DATATYPE;

    // Create datatype
    int blocklen[3] = {1,1,1};
    MPI_Datatype type[3] = { MPI_INT, MPI_DOUBLE, MPI_DOUBLE };
    MPI_Aint disp[3] = {0, 4, 12};
    MPI_Type_create_struct(3, blocklen, disp, type, &TIMEDATA_DATATYPE);
    MPI_Type_commit(&TIMEDATA_DATATYPE);

    // Open file
    offset = 20*world_rank;

    MPI_File_open(MPI_COMM_WORLD, "test.bin", MPI_MODE_CREATE | MPI_MODE_WRONLY,
            MPI_INFO_NULL, &fh);

    // Write to file
    test t1, t2;
    MPI_File_write_at(fh, offset, &t1, 1, TIMEDATA_DATATYPE, &status);
    MPI_File_write_at(fh, offset, &t2, 1, TIMEDATA_DATATYPE, &status);

    // Close file
    MPI_File_close(&fh);

    MPI_Finalize();
    
    return 0;
}

Run and compiled with运行和编译

mpic++ Test.cpp
mpirun -n 2 a.out 

So in the code above, I basically want to write to the same file twice.所以在上面的代码中,我基本上想两次写入同一个文件。 Each time from a different process.每次来自不同的过程。 The data is a struct of the format int, double, double so 4+8+8=20 bytes of data.数据是格式为 int、double、double 的结构体,因此 4+8+8=20 字节的数据。 We have two objects of that struct but both are initialized with the same values.我们有该结构的两个对象,但都使用相同的值初始化。 So we write two blocks of 20 bytes of data into the file test.bin and I expect to see this "symmetry" in the binary representation but I get: (I provide two different outputs of two different cli tools.)因此,我们将两个 20 字节的数据块写入文件 test.bin,我希望在二进制表示中看到这种“对称性”,但我得到:(我提供了两个不同 cli 工具的两个不同输出。)

$ xxd test.bin 
00000000: 0100 0000 fe7f 0000 0000 0000 0000 e03f  ...............?
00000010: 0000 e03f 0100 0000 ff7f 0000 0000 0000  ................
00000020: 0000 e03f 0000 0000                      ...?....

$ hexdump test.bin 
0000000 0001 0000 7ffe 0000 0000 0000 0000 3fe0
0000010 0000 0000 0001 0000 7fff 0000 0000 0000
0000020 0000 3fe0 0000 0000                    
0000028

Now, if we look at the output of xxd we see:现在,如果我们查看 xxd 的 output,我们会看到:

First 20 bytes:前 20 个字节:

  • Integer: 0100 0000 Integer:0100 0000
  • Double: fe7f 0000 0000 0000双倍:fe7f 0000 0000 0000
  • Double: 0000 e03f 0000 e03f双倍:0000 e03f 0000 e03f

Second 20 bytes:第二个 20 字节:

  • Integer: 0100 0000 Integer:0100 0000
  • Double: ff7f 0000 0000 0000双倍:ff7f 0000 0000 0000
  • Double: 0000 e03f 0000 0000双倍:0000 e03f 0000 0000

Now basically, I'm not fully sure why the doubles here differ.现在基本上,我不完全确定为什么这里的双打不同。

Instead of:代替:

MPI_Aint disp[3] = {0, 4, 12};

do the following:请执行下列操作:

disp[0] = offsetof(test, rank);
disp[1] = offsetof(test, begin);
disp[2] = offsetof(test, end);

do not forget to include " #include <stddef.h> ", and to adapt the offset ( ie, offset = sizeof(test) * world_rank; )不要忘记包含“ #include <stddef.h> ”,并调整偏移量(即, offset = sizeof(test) * world_rank;

Do not try to manually hardcode the offsets, it is better to use offsetof from <stddef.h> to figure it out for you.不要尝试手动硬编码偏移量,最好使用<stddef.h>中的offsetof来为您解决。 There is no guarantee that the padding used inside structures will match the values that you have hardcoded in your array for the displacements ( ie, disp )无法保证结构内部使用的填充将与您在数组中硬编码的位移值相匹配(disp

Structure padding is a concept in C that adds the one or more empty bytes between the memory addresses to align the data in memory.结构填充是 C 中的一个概念,它在 memory 地址之间添加一个或多个空字节,以对齐 memory 中的数据。 ( source ). 来源)。 To a better understanding of padding look into this SO thread为了更好地理解填充查看这个 SO 线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM