簡體   English   中英

MPI_File_write_at:兩次寫入相同的結構會導致二進制文件中的數據塊略有不同

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

我有以下簡單的 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;
}

運行和編譯

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

所以在上面的代碼中,我基本上想兩次寫入同一個文件。 每次來自不同的過程。 數據是格式為 int、double、double 的結構體,因此 4+8+8=20 字節的數據。 我們有該結構的兩個對象,但都使用相同的值初始化。 因此,我們將兩個 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

現在,如果我們查看 xxd 的 output,我們會看到:

前 20 個字節:

  • Integer:0100 0000
  • 雙倍:fe7f 0000 0000 0000
  • 雙倍:0000 e03f 0000 e03f

第二個 20 字節:

  • Integer:0100 0000
  • 雙倍:ff7f 0000 0000 0000
  • 雙倍:0000 e03f 0000 0000

現在基本上,我不完全確定為什么這里的雙打不同。

代替:

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

請執行下列操作:

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

不要忘記包含“ #include <stddef.h> ”,並調整偏移量(即, offset = sizeof(test) * world_rank;

不要嘗試手動硬編碼偏移量,最好使用<stddef.h>中的offsetof來為您解決。 無法保證結構內部使用的填充將與您在數組中硬編碼的位移值相匹配(disp

結構填充是 C 中的一個概念,它在 memory 地址之間添加一個或多個空字節,以對齊 memory 中的數據。 來源)。 為了更好地理解填充查看這個 SO 線程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM