As suggested on my previous question, I am posting my revised code for feedback.
One thing that caught my attention is that my program actually runs slower after adding the modifications. It was previously running near 128 iterations per second on a single core machine and 382 in a 4-core machine. It now runs at 125 in the single core and 360 in the 4-core machine. I am not sure the way I was managing memory in my first version is faster or if I implemented it wrong.
Grid3d.h:
#ifndef _GRID3D_
#define _GRID3D_
#include <iostream>
class Grid3d
{
private:
size_t M, N, L;
double* buffer;
size_t compute_index(size_t, size_t, size_t) const;
public:
//Constructores
Grid3d(size_t,size_t,size_t);
Grid3d();
Grid3d(const Grid3d&);
~Grid3d();
//Operadores
double& operator()(size_t, size_t, size_t);
double operator()(size_t, size_t, size_t) const;
Grid3d& operator=(Grid3d);
//Acceso
int get_L();
int get_M();
int get_N();
double get(size_t,size_t,size_t) const;
void reset();
};
std::ostream & operator<< (std::ostream &,Grid3d);
#endif
Grid3d.cc:
#include "Grid3d.h"
#include <cmath>
#include <iomanip>
#include <cassert>
using namespace std;
//------------------------------------------------------------------
// Constructores
//------------------------------------------------------------------
//Constructor
Grid3d::Grid3d(size_t M, size_t N, size_t L)
: M(M), N(N), L(L), buffer(new double[M * N * L])
{
for (size_t l=0;l<M*N*L;l++){
buffer[l] = NAN;
}
}
//Constructor vacĂo
Grid3d::Grid3d()
:M(0), N(0), L(0)
{
buffer = NULL;
}
//Constructor copia
Grid3d::Grid3d(const Grid3d &other)
:M(other.M), N(other.N), L(other.L)
{
buffer = new double[M * N * L];
for (size_t l=0;l<M*N*L;l++){
buffer[l] = other.buffer[l];
}
}
//Destructor
Grid3d::~Grid3d() { delete [] buffer; }
//------------------------------------------------------------------
// Operadores
//------------------------------------------------------------------
//Access operator ():
double& Grid3d::operator()(size_t i, size_t j, size_t k)
{
assert(i >= 0 and i < M);
assert(j >= 0 and j < N);
assert(k >= 0 and k < L);
return buffer[compute_index(i, j, k)];
}
//Access operator () const:
double Grid3d::operator()(size_t i, size_t j, size_t k) const
{
assert(i >= 0 and i < M);
assert(j >= 0 and j < N);
assert(k >= 0 and k < L);
return buffer[compute_index(i, j, k)];
}
//Assignment operator
Grid3d& Grid3d::operator=(Grid3d other)
{
using std::swap;
swap(M, other.M);
swap(N, other.N);
swap(L, other.L);
swap(buffer, other.buffer);
return *this;
}
//------------------------------------------------------------------
// Acceso
//------------------------------------------------------------------
size_t Grid3d::compute_index(size_t i, size_t j, size_t k) const
{
return k * (M * N) + i * N + j;
}
int Grid3d::get_L()
{
return L;
}
int Grid3d::get_M()
{
return M;
}
int Grid3d::get_N()
{
return N;
}
double Grid3d::get(size_t i, size_t j, size_t k) const
{
assert(i >= 0 and i < M);
assert(j >= 0 and j < N);
assert(k >= 0 and k < L);
return buffer[compute_index(i, j, k)];
}
void Grid3d::reset()
{
for (size_t l=0;l<M*N*L;l++){
buffer[l] = NAN;
}
}
//------------------------------------------------------------------
// Others
//------------------------------------------------------------------
//cout
std::ostream & operator << (std::ostream & os , Grid3d g)
{
int M = g.get_M();
int N = g.get_N();
int L = g.get_L();
for (int k=0;k<L;k++){
cout << "k = " << k << endl;
for (int i=0;i<M;i++){
for (int j=0;j<N;j++){
cout.width(10);
os << setprecision(3) << g.get(i,j,k)<< " ";
}
os << endl;
}
os << endl;
}
return os;
}