Introduction C++ Template Meta Programming Template Metaprogram- ming
A Bad Francesco Nidito Example A Good Example
Conclusions Programmazione Avanzata AA 2005/06 Outline
C++ Template Meta Programming 1 Introduction
Introduction 2 Template Metaprogramming Template Metaprogram- ming
3 A Bad Example A Bad Example
A Good 4 A Good Example Example Conclusions 5 Conclusions
Reference: K. Czarnecki, U. W. Eisenecker, “Generative Programming: Methods, Tools, and Applications”, Chapter 10 What Is Template Metaprogramming?
C++ Template Meta Programming
Introduction
Template At this moment is quite difficult to give a definition. First Metaprogram- ming define two terms: A Bad Template Example Metaprogramming A Good Example
Conclusions What Are Templates?
C++ Template Meta Programming
Templates are a C++ technique to create Generic Code Introduction Template Some templates are in C++ Standard and can be found in Metaprogram- STL ming A Bad The first version of STL architecture was made by Example A Good Alexander Stepanov Example Some examples of templates in STL are: std::vector, Conclusions std::map and std::list C++ Templates Example: Very Simple Array
C++ Template Meta template
T a[L]; Introduction
public: Template Metaprogram- VerySimpleArray(){ ming
for(int i=0; i < L; ++i) a[i] = T(); A Bad } Example A Good T& Get(unsigned int i){return a[i];} Example void Set(unsigned int i, T& v){a[i] = v;} Conclusions };
VerySimpleArray
C++ Template template
... A Bad template
/usr/include/c++/3.3.2/bits/std vector.h /usr/include/c++/3.3.2/bits/std bvector.h What Is Metaprogramming?
C++ Template Meta Metaprogramming means writing programs that can Programming modify other programs or themselves The modification can happen at run time or at compile Introduction Template time Metaprogram- ming
Compilers are an example of metaprograming: they take a A Bad program in an input language (C, Java...) and produce Example A Good another program (with same semantic) in an output Example
language (machine code, bytecode... ) Conclusions Metaprograms have three advantages: Produce code quickly Lift abstraction Produce correct code (if the metaprogram is correct) What Is Template Metaprogramming?
C++ Template Meta Programming
Introduction Now it is time for the replay, Template Metaprograming Template Metaprogram- is... ming A Bad Producing metaprograms in C++ using templates Example But... wait a second... why do I need Template A Good Example Metaprogramming? Conclusions The Need For Speed
C++ Template int Fact(int x){ Meta Programming int acc = 1;
for(;x>0;--x) acc*=x; Introduction
return acc; Template Metaprogram- } ming
A Bad int a, b; Example A Good a = read_int_from_stdin(); Example
b = Fact(a); //we compute at run time Conclusions ... b = Fact(5); //we can compute at compile //time but we do not
We pay the time to compute something that is a constant! Naive Solution
C++ ... Template Meta Programming b = 120; //b = Fact(5); Introduction
Template The solution is not elegant. We need to place a lot Magic Metaprogram- ming Numbers in the code. And the magic number does not keep its A Bad meaning (5! = 120 or 42 + 78 = 120 ...). Example We can use a but it is not better: we must provide a A Good #define Example
define for all possible value of the input of Fact. Conclusions ... #define FACT_4 (24) #define FACT_5 (120) ...
b = FACT_5; Template Metaprogramming Solution
C++ Template Meta Programming The general idea is to use the compiler to do some computation at compile time. Introduction Template To do this we need a only a C++ compiler that provides Metaprogram- ming Templates A Bad This can be done because the compiler, when compiles Example A Good Templates, produces code Example If we produce the right code (e.g. the sum of constant Conclusions terms), the compiler optimize and do constant folding But we can do more... First Step
C++ Template Meta Programming
template< int i> Introduction
struct C { Template Metaprogram- enum { RES = i }; ming
}; A Bad Example
A Good cout <<_ C<2>::RES; Example
Conclusions
C<2>::RES is substituted by the compiler with 2: it is a cost ant and we can optimize. Back To Factorial
C++ Template Meta template
enum { RET = n * Fact
}; Template Metaprogram- ming
template<> A Bad struct Fact<1> { Example A Good enum { RET = 1 }; Example }; Conclusions
int b = Fact<5>::RET; // == 120
To do computation we must unroll templates: a kind of recursion Where is The Trick?
C++ Template Meta Programming
enum { RET = 5 * Fact<4>::RET }; Introduction
enum { RET = 5 * 4 * Fact<3>::RET }; Template Metaprogram- enum { RET = 5 * 4 * 3 * Fact<2>::RET }; ming
enum { RET = 5 * 4 * 3 * 2 * Fact<1>::RET }; A Bad enum { RET = 5 * 4 * 3 * 2 * 1 }; Example A Good enum { RET = 120 }; Example
Conclusions b = 120; //Fact<5>::RET; C++ Template Metaprogramming Operators
C++ Template Meta Programming template
C++ Template Meta class CopyingGC { Programming public: void Collect() /*...*/ Introduction Template }; Metaprogram- ming
A Bad class MarkAndSweepGC { Example
public: A Good void Collect() /*...*/ Example }; Conclusions
IF
C++ Template Meta Programming
Introduction Template
C++ inline int Power(const int x, int n){ Template Meta int p = 1; Programming for(;n>0; --n) p *= x; return p; Introduction } Template Metaprogram- ming
A Bad We can specialize Power code for particular cases: Example A Good inline int Power3(const int x){ Example int p = 1; Conclusions p *= x; p *= x; p *= x; return p; } C++ Template Metaprogramming Code Generation
C++ template
return 1; A Good } Example Conclusions template<> inline int Power<0>(const int x){ return 1; }
cout <<_ Power<4>(m); C++ Template Metaprogramming Code Generation
C++ Template _ Meta cout << Power<4>(m); Programming
_ cout << Power<3>(m) * m; Introduction
Template Metaprogram- cout <<_ Power<2>(m) * m * m; ming
A Bad cout <<_ Power<2>(m) * m * m * m; Example A Good Example cout <<_ Power<1>(m) * m * m * m * m; Conclusions
cout <<_ 1 * m * m * m * m;
cout <<_ m * m * m * m; C++ Template Metaprogramming Loop Unrolling(1)
C++ Template Meta Programming template
B::body(n * m/n + i); Conclusions } } }; C++ Template Metaprogramming Loop Unrolling(2)
C++ Template Meta template
}; A Good Example template
C++ Template Meta Programming
Introduction
We can generate code for multiple purposes: Template Metaprogram- Vector operations ming
Math functions A Bad ... Example A Good Exercise: try to write some C++ Template Example
Metaprograming functions and control structures (WHILE) Conclusions C++ Template Metaprogramming Data Structures
C++ Template Meta Programming
Introduction Lisp lovers know very well this code: Template Metaprogram- (cons 1 (cons 2 (cons 3 (cons 4 (cons nil)))) ming A Bad The previous code represents the list: Example
(1 2 3 4) A Good Example C++ Template Metaprogrammers have this too... Conclusions C++ Template Metaprogramming Data Structures
C++ Template Meta template
A Good typedef Cons<1, Cons<2, Nil()> > V; Example //V::item == 1; Conclusions //V::next::item == 2; //V::next::next == Nil;
Exercise: try to create a Tree Total Loop Unroll
C++ Template Meta Programming
Introduction
Template We want to copy all elements of an int array into another Metaprogram- ming
We want to do it fast A Bad Example We can use an approach similar to FOR template A Good metastructure Example Conclusions Total Loop Unroll (C++ Code 1)
C++ Template Meta Programming template
C++ Template template
A Good template <> Example Conclusions struct TMP_COPY_UNROLL<1> { static void iteration(int i, int* f, int* t){ *t++ = *f++; } }; Performance Results
C++ Template Meta We measure the “Execution Time” of various values of Programming unroll and...... surprise Introduction Template # Loop Unroll Execution Time Metaprogram- 1 3.16 ming A Bad 10 1.79 Example 50 2.23 A Good Example 100 2.70 Conclusions 500 2.81 1000 2.84 2000 4.83 5000 19.48 Performance Results (Chart)
C++ Template Meta Programming 19.48
Introduction
Template Metaprogram- ming
A Bad Example
A Good Example
Conclusions 3.16
1.79 Performance Results (An Explanation)
C++ Template Meta Programming
Introduction
Template Why? Metaprogram- ming
Loop unroll produce very big executable files A Bad Big executable files cannot be kept in the code cache Example A Good We have a lot of cache misses Example Conclusions Boost.MPL
C++ Template Meta Programming Meta Programming Library is part of Boost library
Boost is a portable C++ library that provides a big Introduction number utilities: Template Metaprogram- Threads ming
Containers A Bad Math Example I/O A Good Example Much more (circa 70 sub libraries)... Conclusions “The Boost.MPL library is a general-purpose, high-level C++ template metaprogramming framework of compile-time algorithms, sequences and metafunctions” Boost.MPL (Example)
C++ Template Meta Programming typedef list_c
C++ Template Meta Programming
Introduction C++ template metaprogramming is a powerful method to Template do computational tasks at compile time Metaprogram- ming
First approach is not very easy A Bad Example Some lib is present (general, matrix/math...) A Good Must be careful on compile errors (the templates tree is Example unrolled!) Conclusions