Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
大小灵活的结构的MPI派生数据类型 我试图在C++中发送/ReV这样的数据结构: /*伪代码*/ 常量int N=getN();//在编译时不可用 常量int M=getM(); 结构包{ int foo; 双杠; /*我知道数组成员不是这样工作的, 这是伪代码*/ 整数触发器[N]; 双泡[M]; };_C++_Mpi_Memory Alignment - Fatal编程技术网

大小灵活的结构的MPI派生数据类型 我试图在C++中发送/ReV这样的数据结构: /*伪代码*/ 常量int N=getN();//在编译时不可用 常量int M=getM(); 结构包{ int foo; 双杠; /*我知道数组成员不是这样工作的, 这是伪代码*/ 整数触发器[N]; 双泡[M]; };

大小灵活的结构的MPI派生数据类型 我试图在C++中发送/ReV这样的数据结构: /*伪代码*/ 常量int N=getN();//在编译时不可用 常量int M=getM(); 结构包{ int foo; 双杠; /*我知道数组成员不是这样工作的, 这是伪代码*/ 整数触发器[N]; 双泡[M]; };,c++,mpi,memory-alignment,C++,Mpi,Memory Alignment,由于M和N在运行时是常量,因此我可以执行MPI\u Type\u create\u struct(),并且新的数据类型在整个过程中都会很好 我的问题是如何实现上述数据结构 std::vector无法工作,因为它不是串行的 灵活的数组成员如 > [/]>或 [0 ]是C++中的未定义行为,它对M和 N 因此,我必须使用malloc(): 类包{ 公众: //缓冲区中[]:条、气泡[]、foo、flop[] //按照这个顺序,一个直接跟在另一个后面。 包(): 缓冲区((双*)malloc((M+1

由于
M
N
在运行时是常量,因此我可以执行
MPI\u Type\u create\u struct()
,并且新的数据类型在整个过程中都会很好

我的问题是如何实现上述数据结构

std::vector
无法工作,因为它不是串行的

灵活的数组成员如<> > [/]>或<代码> [0 ]<代码>是C++中的未定义行为,它对<>M和 N 因此,我必须使用

malloc()

类包{
公众:
//缓冲区中[]:条、气泡[]、foo、flop[]
//按照这个顺序,一个直接跟在另一个后面。
包():
缓冲区((双*)malloc((M+1)*sizeof(双)*
(N+1)*sizeof(int)),
条(缓冲器),气泡(缓冲器+1),
foo((int*)(blep+M)),
flop(foo+1){}
~Package(){
自由(缓冲);
}
//构造/释放派生数据类型
静态无效初始化(未签名inN、未签名inM){
N=客栈;
M=inM;
MPI_Aint偏移量[2]={0,(int)(sizeof(double))*(M+1)};
int块[2]={M+1,N+1};
MPI_数据类型[2]={MPI_DOUBLE,MPI_INT};
MPI类型创建结构(2、块、偏移、类型和packageType);
MPI_类型_提交(&packageType);
}
静态void finalize(){
无MPI类型(和packageType);
}
int发送(int秩,int标记){
返回MPI_发送(缓冲区,1,packageType,
排名、标签、MPI_COMM_WORLD);
}
int recv(int秩,int标记){
返回MPI_Recv(缓冲区,1,packageType,
排名、标签、MPI_COMM_WORLD、,
MPI_状态_忽略);
}
私人:
双*缓冲器;
静态int-M;
静态int N;
静态MPI_数据类型packageType;
公众:
//接口变量
双*常数条;
双*常量气泡;
int*const foo;
int*const触发器;
};
int包::N=0;
int包::M=0;
MPI_数据类型包::packageType=MPI_字符;
我测试了上面的代码,它似乎工作正常,但我不确定我是否在做一些实际上是未定义的行为。具体而言:

  • 使用
    sizeof()
    进行
    MPI\u Type\u create\u struct()
    可以吗?我发现一些示例使用了
    MPI\u Type\u get\u extent()
    ,我不知道有什么区别

  • 我不确定将新数据类型存储在
    静态成员中是否是一个好主意。相反,我发现的示例将其作为一个论点传递。有什么具体的理由这样做吗

  • 如果这个方法是可移植的,我也感到困惑。我希望它应该像基于
    struct
    的方法一样可移植,但也许我遗漏了什么

  • 如果这个方法是可移植的,我也感到困惑。我希望它应该像基于结构的方法一样可移植,但也许我遗漏了什么

    一,。假设您有一些类型
    A
    B
    ,而不是
    double
    int
    。然后可能会发生类型为
    B
    的对象(您在
    A
    s之后为其分配空间)未对齐的情况。在某些体系结构上,尝试在(4N+2)字节边界处访问此类对象(例如,
    int
    )将导致总线错误。因此,在一般情况下,必须确保在第一个
    B
    对象之前填充正确。当您使用
    struct
    时,编译器会为您执行此操作

    二,。您访问
    缓冲区的方式是UB。基本上你是这样做的:

    double*buffer=reinterpret_cast(malloc(…);
    双*条=缓冲器;
    int*foo=reinterpret_cast(缓冲区+1);
    做某事(缓冲);
    双杠_值=*杠;//这是UB
    int foo_value=*foo;//我也是
    
    这里的问题是在
    *bar
    *foo
    处没有类型为
    double
    int
    的对象。您可以使用placement
    new
    创建它们:

    char* buffer = reinterpret_cast<char*>(malloc(...));
    double* bar = new(buffer) double;
    int* foo = new(buffer + sizeof(double)) int;
    
    char*buffer=reinterpret_cast(malloc(…);
    双*条=新(缓冲区)双;
    int*foo=new(buffer+sizeof(double))int;
    
    请参阅

    对于数组,可以使用
    std::uninitialized_default_construct
    构造给定范围内的对象

    我不确定将新数据类型存储在静态成员中是否是一个好主意。相反,我发现的示例将其作为一个论点传递。有什么具体的理由这样做吗

    如果
    N
    M
    是静态的,那么将
    packageType
    也设置为静态似乎很好。如果只有一种类型的
    具有固定的
    N
    M
    ,则可能希望避免每次构造
    包时调用
    MPI\u type\u create\u struct
    ,以创建基本相同的MPI数据类型


    但是这种设计看起来不太好:在第一次构造之前应该调用
    initialize()
    。可能您可以创建一个工厂,首先创建MPI数据类型,然后根据用户请求使用类似于
    Package make\u Package()
    的东西构造
    Package
    。那么每个工厂都可以有自己的非静态
    N
    M

    @Evg你所说的
    std::vector
    不是串行的是什么意思
    std::vector
    本质上是一个标准数组的奇特接口。。。它只是提供了一些功能,让你的生活更轻松。。。请看一看(它提供了对底层数组的访问)@Evg您应该只对包含内部数据的类使用
    static
    关键字