I need to dynamically allocate 2D/3D arrays in c++. I would like these to have contiguous memory, for purposes of sending/receiving with MPI. Is there any advice on how to dynamically allocate 2D/3D matrices, with contiguous memory, and be able to access/mutate the elements of these matrices efficiently? I currently use a c++ template to manage matrices. I am showing a small excerpt below for the 3D case. To my understanding, this does not allocate memory contiguously.
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];
}
};
Many posts recommend using a 1D vector, and then accessing the elements using index math. Perhaps like:
// get value
Type get(int i, int j, int k)
{
int NxNy=Nx_*Ny_;
return Vec[i + j * Ny_ + k * NxNy];
}
My concern is that this requires 4 operations (2 additions and 2 multiplications) per get/put. That seems inefficient when working on very large matrices (~1 billion elements) using triple nested for-loops. However, given my limited experience with c and c++, it has also occurred to me that perhaps my original template class above also requires multiple operations per get/put, and they are just hidden under the "hood" of how c++ manages memory.
In summary: is there any advice on how to dynamically allocate 2D/3D matrices, with contiguous memory, and access their elements efficiently?