C++ Design Techniques Ganesh Bikshandi Christoph Von Praun (IBM) Basilio Fraguela

Download Report

Transcript C++ Design Techniques Ganesh Bikshandi Christoph Von Praun (IBM) Basilio Fraguela

C++ Design Techniques
Ganesh Bikshandi
Christoph Von Praun (IBM)
Basilio Fraguela
Jia Guo
C++ Goals
●
Library development
–
Data Abstraction
●
–
Object-oriented Programming
●
–
vector <int>, Stack, Queue etc.
Virtual functions, inheritance
Safety
●
27/05/2016
Strict type conformance
C++ Design Techniques
2
Templates
●
Parameterized types
●
Unbounded set of 'related' types
–
List<int>, List<double>
●
Class Templates
●
Function Templates
27/05/2016
C++ Design Techniques
3
Example
template <class T>
class Array
{
};
class Array<double>
{
};
int main () {
Array<int> a;
Array<double> b;
}
27/05/2016
C++ Design Techniques
4
Example
template <class T, int rank>
class Array
{
};
class Array<double, 2>
{
};
int main () {
Array<int, 3> a;
Array<double, 2> b;
}
27/05/2016
C++ Design Techniques
5
Virtual Functions
struct base {
virtual void vf1();
};
class derived : public base {
public:
void vf1();
};
void g (base* bp) {
bp->vf1();
}
27/05/2016
int main () {
derived d;
base b;
g (&d); //calls derived::vf1
g (&b); //calls base::vf1
}
C++ Design Techniques
6
Virtual Function mechanics
(single inheritance)
.....
vptr;
.....
&derived::vf1
derived
.....
vptr;
.....
&base::vf1
base
27/05/2016
C++ Design Techniques
7
Virtual Functions
struct base {
virtual void vf1();
};
class derived : public base {
public:
void vf1();
};
void g (base* bp) {
bp->vf1();
}
27/05/2016
(*(bp->vptr[0]))(
int main () {
derived d;
base b;
g (&d); //calls derived::vf1
g (&b); //calls base::vf1
C++ Design Techniques
}
8
Space Cost
●
Space
–
One vptr per object
–
One vtable per class (usually).
Growth factor = sizeof(object) + 1
---------------------------sizeof(object)
27/05/2016
C++ Design Techniques
9
Time Cost
●
Direct cost
–
●
Extra memory references/call
Indirect cost
–
Restricts inlining
●
Restricts loop invariant removal
–
–
Restricts some more optimizations
Pipeline Stalls due to branch misprediction
27/05/2016
C++ Design Techniques
10
Purpose
class Matrix { //Abstract class
public:
virtual double operator()(int i, int j) = 0;
};
class SymmetricMatrix : public Matrix { //concrete class
double operator()(int i, int j) { ... }
};
class UpperTriMatrix : public Matrix { //concrete class
double operator()(int i, int j) { ... }
} ;
double sum (Matrix& A) { ... }
SymmetricMatrix A;
sum (A);
27/05/2016
C++ Design Techniques
11
Problem
●
Sizeof (f) is small && freqency(f) is high
–
This is not a rare occurrence
for (int i = 0; i < 100000; i++ )
for (int j = 0; j < 100000; j++)
... = a(i, j);
27/05/2016
C++ Design Techniques
12
Static polymorphism
template<class T_leaftype>
class Matrix {
public:
double operator()(int i, int j) {
private:
T_leaftype leaf;
};
class SymmetricMatrix {
double operator () (int i, int
};
class UpperTriMatrix {
double operator () (int i, int
} ;
template <class T_leaftype>
double sum (Matrix <T_leaftype>& a)
return leaf (i,j); }
j) {...}
j) {....}
{...}
Matrix<SymmetricMatrix> A;
sum (A);
27/05/2016
C++ Design Techniques
13
Static polymorphism
template<class T_leaftype>
class Matrix {
public:
T_leaftype& asLeaf()
{ return static_cast<T_leaftype&>(*this); }
double operator()(int i, int j)
{ return asLeaf()(i,j); }
// delegate to leaf
};
class SymmetricMatrix : public Matrix<SymmetricMatrix> {
};
class UpperTriMatrix : public Matrix<UpperTriMatrix> {
} ;
SymmetricMatrix A;
sum (A);
27/05/2016
C++ Design Techniques
14
Usage in HTALib
Class HTA<L>{
public:
HTA<L-1> operator () (int i, int j){
return wrapped_(i, j);
}
private:
HTAImpl<L> wrapped_;
};
Class HTAImpl<L>{ //HTA
};
class HTAImpl<0>{ //Leaf
};
27/05/2016
C++ Design Techniques
15
Operator Overloading
●
●
Enables clean syntax
–
Array a = c + d;
–
String s = a + b;
Known restrictions
–
Only valid C++ operators
–
Operator[] can take only one argument
27/05/2016
C++ Design Techniques
16
Cost of operator overloading
Z = A + B + C;
.....
tmp1 = A.clone();
for (int i = 0; i < size; i++)
tmp1.data_[i] = A.data_[i] + B.data_[i];
.....
tmp2 = tmp1.clone();
for (int i = 0; i < size; i++)
tmp2.data_[i] = tmp1.data_[i] + C.data_[i];
....
for (int i = 0; i < size; i++)
Z.data_[i] = tmp2.data_[i];
27/05/2016
C++ Design Techniques
17
Cost of operator overloading
Z = A + B + C;
new overhead
loop overhead
.....
2N/ M * More memory traffic
tmp1 = A.clone();
for (int i = 0; i < size; i++)
tmp1.data_[i] = A.data_[i] + B.data_[i];
.....
tmp2 = tmp1.clone();
for (int i = 0; i < size; i++)
tmp2.data_[i] = tmp1.data_[i] + C.data_[i];
....
for (int i = 0; i < size; i++)
Z.data_[i] = tmp2.data_[i];
27/05/2016
C++ Design Techniques
18
Stencil Computations
B = A[I, J] +
A[I-1, J] + A[I+1, J] +
A[I, J-1] + A[I,J+1] +
A[I-1, J-1] + A[I+1, J-1] +
A[I-1, J+1] + A[I+1, J+1]
(factor of 16 slow down)
(double check)
27/05/2016
C++ Design Techniques
19
Expression Templates
●
Idea:
–
Delay the evaluation of expression
–
Construct an hypothetical parse tree of expression
–
Evaluate it on assignment (use)
27/05/2016
C++ Design Techniques
20
Expression Templates
Array A, B, C, D;
D = A + B + C;
D = X<X<Array,plus,Array>,plus,Array>();
27/05/2016
C++ Design Techniques
21
Expression Templates
struct plus { };
class Array { };
// Represents addition
// some array class
template<class Left, class Op, class Right>
class X { };
template<class T>
X<T, plus, Array> operator+(T, Array)
{
return X<T, plus, Array>();
}
27/05/2016
C++ Design Techniques
22
Expression Templates
Array A, B, C, D;
D = A + B + C;
= X<Array,plus,Array>() + C;
= X<X<Array,plus,Array>,plus,Array>();
C
A
27/05/2016
B
C++ Design Techniques
23
Expression Templates
struct Array {
....
template<class Left,class Op, class Right>
void operator=(X<Left,Op,Right> expression)
{
for (int i=0; i < N_; ++i)
data_[i] = expression[i];
}
double operator[](int i)
{ return data_[i]; }
....
};
27/05/2016
C++ Design Techniques
24
Expression Templates
template<class Left, class Op, class Right>
struct X {
Left leftNode_;
Right rightNode_;
double operator[](int i)
{ return Op::apply(leftNode_[i],rightNode_[i]); }
};
struct plus {
static double apply(double a, double b) {
return a+b;
};
};
27/05/2016
C++ Design Techniques
25
Expression Templates
for (int i=0; i < D.N_; ++i)
D.data_[i] = A.data_[i] + B.data_[i] + C.data_[i];
27/05/2016
C++ Design Techniques
26
Template Meta programs
●
Compile time programs
–
Sophisticated than MACROs
●
Compile time specialization of algorithms
●
Partial evaluation of programs
–
P (S, V) = Ps (V)
e.g . ∑ fj e(2πikj) (Prof. Padua is there a better example?)
●
Turing Complete
27/05/2016
C++ Design Techniques
27
Template Meta Programming
template <int N>
struct fact {
static const int value = N * fact<N-1>::val ;
};
struct fact<1> {
static const int val = 1;
};
int main (int argc, char** argv) {
cout << fact<5>::val << endl;
}
27/05/2016
C++ Design Techniques
28
Template Meta Programs
●
Traditional loop optimizations
–
Compare with macros
template <typename T, int DIM>
class VectorOps
{
static inline int dotProduct(const T &x, const T &y)
{
return x[DIM-1] * y[DIM-1] +
VectorOps<T, DIM-1>::dotProduct (x, y);
}
};
VectorOps<int[DIM], DIM>::dotProduct(x, y);
27/05/2016
C++ Design Techniques
29
Template Meta Programs
●
Avoiding costly if-else switches
template <int L, int M>
HTA <(L > M) ? L : M>
operator+ (HTA<L>& lhs, HTA<M>& rhs){
return add_<M, (L > M)>::compute (lhs, rhs);
}
template <int L, bool flag>
struct add_{....};
};
template <int L>
struct add_<L, false> {...};
27/05/2016
C++ Design Techniques
30
Other Patterns
●
●
Productivity
–
Traits
–
Type promotion
Packages
–
PETE
●
27/05/2016
Automated generation of ETs
C++ Design Techniques
31
Conclusion
●
Large scale libraries have numerous overheads
from C++ constructs
–
●
Virtual functions, operator overloading.
Side-effects of templates are accidental
discoveries, but effective
●
Fills the C++ - FORTRAN performance gap
●
Drawbacks:
–
complex design, code growth.
27/05/2016
C++ Design Techniques
32
Thanks
●
Todd Veldhuizen
–
(osl.iu.edu/~tveldhui)
27/05/2016
C++ Design Techniques
33