Gå til innhold

Matrise operasjoner v.h.a. templates


Anbefalte innlegg

Bruker expression templates for å addere sammen matriser uten å bruke temporaries. Tror hvertfall det er det jeg gjør.. Har også tradisjonell kode for addisjon v.h.a. temporaries for å sammenlikne.

Med uttrykket F = A + B + C med 3 x 1 matriser er template metoden dobbelt så rask, mens hvis jeg utvider til F = A + B + C + D (+ E) blir den mye tregere enn den tradisjonelle metoden.. Noe er åpenbart galt.

 

Kan noen ta en titt på koden og prøve å hjelpe meg litt:

 

// test7.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

template<typename T>
class plus {
public:
static T apply(const T& lhs, const T& rhs) {
 return lhs + rhs;
}
};

template<typename T, template<class> class O, class L, class R>
class binexp {
const L& lhs;
const R& rhs;
public:
binexp(const L& l, const R& r) : lhs(l), rhs(r) {
}
const T eval(const int i, const int j) const {
 return O<T>::apply(lhs.eval(i, j), rhs.eval(i, j));
}
};

template<typename T, int N, int M>
class matrix {
public:
T m[N][M];

const T& eval(const int i, const int j) const {
 return m[i][j];
}

// Håper compileren unroller loopen, men dens ytelse påvirkes
// jo ikke av uttrykkets dybde, i motsetning til den trivielle implementasjonen.
template<template<class> class O, class L, class R>
matrix& operator =(binexp<T, O, L, R>& exp) {
 for(int i = 0; i < N; ++i) {
 	for(int j = 0; j < M; ++j) {
   m[i][j] = exp.eval(i, j);
 	}
 }
 return *this;
}

// Bruker denne for sammenlikning.
// Kommenterer da ut de to andre operator overloadingene.
/*matrix operator +(const matrix& mat) const {
 matrix temp;
 for(int i = 0; i < N; ++i) {
 	for(int j = 0; j < M; ++j) {
   temp.m[i][j] = m[i][j] + mat.m[i][j];
 	}
 }
 return temp;
}*/

void print() {
 for(int i = 0; i < N; ++i) {
 	std::cout << "[ ";
 	for(int j = 0; j < M; ++j) {
   std::cout << m[i][j] << " ";
 	}
 	std::cout << "]" << std::endl;
 }
 std::cout << std::endl;
}
};

template<typename T, class L, int N, int M>
binexp<T, plus, L, matrix<T, N, M> > operator +(const L& lhs, const matrix<T, N, M>& rhs) {
return binexp<T, plus, L, matrix<T, N, M> >(lhs, rhs);
}

int _tmain(int argc, _TCHAR* argv[])
{
matrix<int, 3, 1> A, B, C, D, E, F;

A.m[0][0] = 1;
A.m[1][0] = 1;
A.m[2][0] = 1;

B.m[0][0] = 1;
B.m[1][0] = 2;
B.m[2][0] = 3;

C.m[0][0] = 1;
C.m[1][0] = 1;
C.m[2][0] = 1;

D.m[0][0] = 2;
D.m[1][0] = 2;
D.m[2][0] = 2;

E.m[0][0] = 1;
E.m[1][0] = 1;
E.m[2][0] = 3;

for(int i = 0; i < 1000000000; ++i) {
 F = A + B + C + D;
}

F.print();

std::cout << "Time taken: " << (float)clock() / 1000.0f << " seconds.\n";

return 0;
}

Lenke til kommentar
Videoannonse
Annonse
Hva med å ta en kikk på tvmet (tvmet.sf.net)? Er ganske ute av dette selv, så selve implementasjonen kan jeg ikke hjelpe deg så mye med (ja, jeg er lat).

Kan jo kikke på kilden, men mistenker at den er såpass kompleks at den ikke kan hjelpe meg noe særlig her. Kanskje gjør den det på en helt annen måte. Men jeg ser jo ikke hva som er galt med det jeg gjør, men av en eller annen merkelig grunn oppfører den seg rart i praksis(ytelsesmessig når jeg øker lengden på uttrykkene).

Lenke til kommentar

Kjappt forslag her;

Hva med å lage en tracer-klasse og se hva som skjer?

 

Pass inn en type (klasse) som oppfører seg som et tall (har en conversion operator f.eks.) og har statiske medlemsvariabler som justeres hver gang et objekt av tracer-klassen blir konstruert, destruert, sammenlignet ..o.s.v.

 

Er eksempelkode her, men vet ikke om dette med tracer og sånnt kan være til hjelp egentlig:

 

http://www.josuttis.com/tmplbook/basics/tracer.hpp.html

http://www.josuttis.com/tmplbook/basics/tracer.cpp.html

http://www.josuttis.com/tmplbook/basics/tracertest.cpp.html

Lenke til kommentar
Det er mye dokumentasjon for tvmet, og jeg tror faktisk at det nevnes ytelsesproblemer når uttrykkene får mange ledd.

Ja det kan se ut til at det bare blir for mye for at compileren skal gjøre noe nyttig ut av det.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...