我需要在c中动态分配2D/3D数组。我希望这些数组具有连续的内存,以便使用MPI发送/接收。有没有关于如何动态分配2D/3D矩阵的建议?并且能够有效地访问/变异这些矩阵的元素??我目前使用C模板来管理矩阵。我在下面展示了一个3D案例的小片段。据我所知,这并不是连续分配内存。
template <class Type>
class Matrix
{
private:
// size of matrix
int Nx_ = 0;
int Ny_ = 0;
int Nz_ = 0;
// matrix
Type*** A3_;
public:
// constructor
Matrix(int Nx, int Ny, int Nz)
{
Nx_ = Nx;
Ny_ = Ny;
Nz_ = Nz;
A3_ = new Type**[Nx];
for (int i = 0; i < Nx; i++)
{
A3_[i] = new Type*[Ny];
for (int j = 0; j < Ny; j++)
{
A3_[i][j] = new Type[Nz];
}
}
}
// insert value
void put(int i, int j, int k, Type a)
{
A3_[i][j][k] = a;
}
// get value
Type get(int i, int j, int k)
{
return A3_[i][j][k];
}
};
许多帖子推荐使用1D向量,然后使用索引数学访问元素。
// get value
Type get(int i, int j, int k)
{
int NxNy=Nx_*Ny_;
return Vec[i + j * Ny_ + k * NxNy];
}
我担心这需要4次手术(2次加法和2次乘法)。这在处理非常大的矩阵时似乎效率很低(~ 10亿个元素)使用三重嵌套的for循环。然而,考虑到我有限的c和c经验,我也想到,也许我上面的原始模板类也需要每个get/put进行多个操作,它们只是隐藏在C管理内存的“引擎盖”下。
总之:对于如何动态分配2D/3D矩阵,使用连续内存,并高效地访问其元素,有什么建议吗?
2条答案
按热度按时间olmpazwi1#
你找到的建议是正确的方向:使用平面1D数据结构和索引转换。
只有你的实现是次优的。我将只概述一般的想法,没有生产准备代码。考虑这样一个循环:
然后你需要安排你的元素,这样对于固定的
K
和J
,所有的get(i,J,K)
在内存中彼此接近。这就是你已经拥有的。现在你只需要一种快速访问它们的方法,这可以通过一个迭代器来实现。迭代器可以简单地是一个指针。你可以沿着这样的路线做一些事情:++it
只是增加了一个指针,这和遍历元素一样便宜。pbgvytdp2#
一维分配并使用索引转换。您可以比使用
get
和set
方法更优雅:这样就可以同时使用
x = mymat(i,j,k)
和mymat(i,j,k) = x
。我还要指出,您可以使用
Vector
和Subarray
数据类型来发送矩阵及其部分。