#include "sopnamsp.h" #include "machdefs.h" #include #include #include #include "tarrinit.h" #include "array.h" #include "ctimer.h" #include "timing.h" #include "srandgen.h" // -------------------------------------------------------- // Programme de mesure d'overhead, lie a l'utilisation des // classes, de NDataBlock et TArray en particulier // Attention, l'operateur * declare ds les classes // ci-dessous denote l'operation multiplication element // par element - Ceci n'est pas le cas pour les Tmatrix // -------------------------------------------------------- // -------- // --------------------------------------------------- // Classe simple de matrice, utilisant les NDataBlock // --------------------------------------------------- template class SimpleMatrix : public AnyDataObj { public: SimpleMatrix(sa_size_t nr, sa_size_t nc); SimpleMatrix(const SimpleMatrix & m); SimpleMatrix(const SimpleMatrix & m, bool share); virtual ~SimpleMatrix(); virtual SimpleMatrix& Set(const SimpleMatrix & a); inline SimpleMatrix& operator = (const SimpleMatrix & a) { return Set(a); } inline T operator()(int r, int c) const { return data_(r*ncol_+c); } inline T& operator()(int r, int c) { return data_(r*ncol_+c); } inline sa_size_t NRows() const {return nrow_; } inline sa_size_t NCols() const {return ncol_; } SimpleMatrix& AddElt(const SimpleMatrix & b); SimpleMatrix& MulElt(const SimpleMatrix & b); protected: sa_size_t ncol_ , nrow_; NDataBlock data_; }; template inline SimpleMatrix operator + (const SimpleMatrix& a, const SimpleMatrix& b) { SimpleMatrix ret(a, false); return(ret.AddElt(b)); } template inline SimpleMatrix operator * (const SimpleMatrix& a, const SimpleMatrix& b) { SimpleMatrix ret(a, false); return(ret.MulElt(b)); } template SimpleMatrix::SimpleMatrix(sa_size_t nr, sa_size_t nc) : nrow_(nr), ncol_(nc), data_(nr*nc) { } template SimpleMatrix::SimpleMatrix(const SimpleMatrix & m) : nrow_(m.nrow_), ncol_(m.ncol_), data_(m.data_) { } template SimpleMatrix::SimpleMatrix(const SimpleMatrix & m, bool share) : nrow_(m.nrow_), ncol_(m.ncol_), data_(m.data_, share) { } template SimpleMatrix::~SimpleMatrix() { } template SimpleMatrix& SimpleMatrix::Set(const SimpleMatrix & b) { if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_)) throw(SzMismatchError("SimpleMatrix::Set() Size(a) != Size(b)")); data_ = b.data_; return(*this); } template SimpleMatrix& SimpleMatrix::AddElt(const SimpleMatrix & b) { if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_)) throw(SzMismatchError("SimpleMatrix::AddElt() Size(a) != Size(b)")); data_ += b.data_; return(*this); } template SimpleMatrix& SimpleMatrix::MulElt(const SimpleMatrix & b) { if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_)) throw(SzMismatchError("SimpleMatrix::MulElt() Size(a) != Size(b)")); data_ *= b.data_; return(*this); } // ------------------------------------------------- // Classe simple de matrice nxm , avec new double // ------------------------------------------------- class VerySimpleMatrix { public: VerySimpleMatrix(int nr, int nc, bool zero=true); VerySimpleMatrix(const VerySimpleMatrix & m); virtual ~VerySimpleMatrix(); virtual VerySimpleMatrix& Set(const VerySimpleMatrix & a); inline VerySimpleMatrix& operator = (const VerySimpleMatrix & a) { return Set(a); } inline double operator()(int r, int c) const { return a_[r*ncol_+c]; } inline double& operator()(int r, int c) { return a_[r*ncol_+c]; } inline int NRows() const {return nrow_; } inline int NCols() const {return ncol_; } VerySimpleMatrix& AddElt(const VerySimpleMatrix & b); VerySimpleMatrix& MulElt(const VerySimpleMatrix & b); protected: int ncol_ , nrow_; double* a_; }; inline VerySimpleMatrix operator + (const VerySimpleMatrix& a, const VerySimpleMatrix& b) { VerySimpleMatrix ret(a); return(ret.AddElt(b)); } inline VerySimpleMatrix operator * (const VerySimpleMatrix& a, const VerySimpleMatrix& b) { VerySimpleMatrix ret(a); return(ret.MulElt(b)); } VerySimpleMatrix::VerySimpleMatrix(int nr, int nc, bool zero) { nrow_ = nr; ncol_ = nc; int l = nrow_ * ncol_; a_ = new double[l]; if (zero) for(int i=0; i class SmallMatrix { public: SmallMatrix() { } SmallMatrix(const SmallMatrix & m) { for(int i=0; i& Set(const SmallMatrix & m) { for(int i=0; i& operator = (const SmallMatrix& a) { return Set(a); } inline T operator()(int r, int c) const { return data_[r*C+c]; } inline T& operator()(int r, int c) { return data_[r*C+c]; } inline int NRows() const {return L; } inline int NCols() const {return C; } inline SmallMatrix & AddElt(const SmallMatrix & m) { for(int i=0; i & MulElt(const SmallMatrix & m) { for(int i=0; i inline SmallMatrix operator + (const SmallMatrix& a, const SmallMatrix& b) { SmallMatrix ret(a); return(ret.AddElt(b)); } template inline SmallMatrix operator * (const SmallMatrix& a, const SmallMatrix& b) { SmallMatrix ret(a); return(ret.MulElt(b)); } // ------------------------------------------------------- // Classe simple de matrice 2x2 - sans allocation memoire // ------------------------------------------------------- class VerySimpleMatrix2x2 { public: inline VerySimpleMatrix2x2() { } inline VerySimpleMatrix2x2(const VerySimpleMatrix2x2 & m) { for(int i=0; i<4; i++) a_[i] = m.a_[i]; } inline ~VerySimpleMatrix2x2() { } inline VerySimpleMatrix2x2& Set(const VerySimpleMatrix2x2 & m) { for(int i=0; i<4; i++) a_[i] = m.a_[i]; return (*this); } inline VerySimpleMatrix2x2& operator = (const VerySimpleMatrix2x2 & a) { return Set(a); } inline double operator()(int r, int c) const { return a_[r*2+c]; } inline double& operator()(int r, int c) { return a_[r*2+c]; } inline int NRows() const {return 2; } inline int NCols() const {return 2; } inline VerySimpleMatrix2x2& AddElt(const VerySimpleMatrix2x2 & m) { for(int i=0; i<4; i++) a_[i] += m.a_[i]; return (*this); } inline VerySimpleMatrix2x2& MulElt(const VerySimpleMatrix2x2 & m) { for(int i=0; i<4; i++) a_[i] *= m.a_[i]; return (*this); } protected: double a_[4]; }; inline VerySimpleMatrix2x2 operator + (const VerySimpleMatrix2x2& a, const VerySimpleMatrix2x2& b) { VerySimpleMatrix2x2 ret(a); return(ret.AddElt(b)); } inline VerySimpleMatrix2x2 operator * (const VerySimpleMatrix2x2& a, const VerySimpleMatrix2x2& b) { VerySimpleMatrix2x2 ret(a); return(ret.MulElt(b)); } // ------------------------------------------------------------ // programme de test // Appel: ovharr NLoop [NRow NCol] // NRow = 0 ou NCol = 0 --> test 2x2 only // ------------------------------------------------------------ void add_double_n(int n, double* x1, double* x2, double* x3); void mul_double_n(int n, double* x1, double* x2, double* x3); int main(int narg, char* arg[]) { SophyaInit(); InitTim(); // Initializing the CPU timer if (narg < 2) { cout << " Missing argument/ Usage: ovharr NLoop [NRow NCol] \n " << " NRow==0 OR NCol==0 ---> Test 2x2 only \n " << endl; exit(1); } int i,j,k; char buff[128]; int N = atoi(arg[1]); int nrow = 2; int ncol = 2; if (narg > 2) nrow = atoi(arg[2]); if (narg > 3) ncol = atoi(arg[3]); bool fgall = true; if ((nrow == 0) || (ncol == 0)) fgall = false; cout << " ovharr/ Testing TArray overhead - NLoop = " << N << " NRow=" << nrow << " NCol= " << ncol << endl; try { if (fgall) { cout << "1) ------ Overhead using TMatrix ------" << endl; Timer tm("Overhead:TMatrix"); for(k=0; k Matrix * m4 = new Matrix(*m1); m4->MulElt(*m2,*m4); delete m1; delete m2; delete m3; delete m4; // if (k%(N/10) == 0) { // sprintf(buff, "ovharr: Iteration k= %d ",k); // PrtTim(buff); // } } } if (fgall) { cout << "2) ------ Overhead using TMatrix No new ------" << endl; Timer tm("Overhead:TMatrix No new"); for(k=0; k ------" << endl; Timer tm("Overhead:SimpleMatrix"); for(k=0; k * m1 = new SimpleMatrix(nrow, ncol); SimpleMatrix * m2 = new SimpleMatrix(nrow, ncol); SimpleMatrix * m3 = new SimpleMatrix(nrow, ncol); SimpleMatrix * m4 = new SimpleMatrix(nrow, ncol); for(i=0; i NO new ----" << endl; Timer tm("Overhead:SimpleMatrix NO new"); for(k=0; k m1(nrow, ncol); SimpleMatrix m2(nrow, ncol); for(i=0; i m3 = m1 + m2; SimpleMatrix m4 = m1 * m2; } } if (fgall) { cout << "5) ---- Overhead using VerySimpleMatrix( , , zero=true) ----" << endl; Timer tm("Overhead:VerySimpleMatrix( , , zero=true)"); for(k=0; k No new ----" << endl; Timer tm("Overhead:SmallMatrix No new "); for(k=0; k m1,m2; for(i=0; i<4; i++) for(j=0; j<5; j++) { m1(i,j) = k*300+10.*i+j; m2(i,j) = k*550+20.*i+2.*j; } SmallMatrix m3 = m1 + m2; SmallMatrix m4 = m1 * m2; } } { cout << "10) ---- Overhead using SmallMatrix No new ----" << endl; Timer tm("Overhead:SmallMatrix No new"); for(k=0; k m1,m2; for(i=0; i<2; i++) for(j=0; j<2; j++) { m1(i,j) = k*300+10.*i+j; m2(i,j) = k*550+20.*i+2.*j; } SmallMatrixm3 = m1 + m2; SmallMatrixm4 = m1 * m2; } } { cout << "11) ---- Overhead using VerySimpleMatrix2x2 ----" << endl; Timer tm("Overhead:VerySimpleMatrix2x2"); for(k=0; k