473,326 Members | 2,110 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Template Meta Programming

http://osl.iu.edu/~tveldhui/papers/T.../meta-art.html

Can anyone shed some light on the need for stuff like this when using
any of the most modern compilers?

If i have a function :

double Square( double d )
{
return d * d;
}

and use it like this:

int main()
{
double answer = Square( 4.0 );
}

I always assumed that the compiler is cleaver enough to decide that the
function call is not needed and just set 'answer' to 16 in the compiled
machine code. If that is the case, is the use of simple meta templates
irrelevent with modern compilers (esp. see 'Temporary variables' in the
example posted URL above).

I assume that more complex meta programs are still useful today when the
compiler cannot make informed choices about complex code.

Many thanks for your replies,
Jon
Oct 9 '06 #1
8 2253
Jon Rea wrote:
http://osl.iu.edu/~tveldhui/papers/T.../meta-art.html

Can anyone shed some light on the need for stuff like this when using
any of the most modern compilers?

If i have a function :

double Square( double d )
{
return d * d;
}

and use it like this:

int main()
{
double answer = Square( 4.0 );
}

I always assumed that the compiler is cleaver enough to decide that
the function call is not needed and just set 'answer' to 16 in the
compiled machine code. If that is the case, is the use of simple meta
templates irrelevent with modern compilers (esp. see 'Temporary
variables' in the example posted URL above).
How do templates play into this non-template code? Here your 'Square'
always takes a double and returns a double. If you would like to use
any type that defines the "squaring" semantics, you _should_ declare
(and define) 'Square' as a template.
I assume that more complex meta programs are still useful today when
the compiler cannot make informed choices about complex code.
I am not sure what exactly your question/statement means. You seem
to want to simplify template metaprogramming by reducing it to making
compile-time calculations and using the results instead of computing
those values during run-time. But you're discounting the whole other
side of templates: compile-time polymorphism. How come?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 9 '06 #2
Jon Rea wrote:
double Square( double d )
{
return d * d;
}

and use it like this:

int main()
{
double answer = Square( 4.0 );
}

I always assumed that the compiler is cleaver enough to decide that the
function call is not needed and just set 'answer' to 16 in the compiled
machine code. If that is the case, is the use of simple meta templates
irrelevent with modern compilers (esp. see 'Temporary variables' in the
example posted URL above).
The compiler will optimize away the call to Square() if Square() is an
inline function. Some optimizing compilers (such as g++ with the -O3
option) can inline functions automatically.

Template metaprogramming is another thing: it allows to automatically
generate specialized (and thus efficient) code. E.g., if you want to
create a function that computes integer powers, you could use a for loop:

double power(int i, double x) {
double res = 1.0
for (; i 0; i--)
res *= x;
return res;
}

The compiler cannot optimize a call to power(3,x) to x*x*x. But you can
achieve this using the following function:

template<int N>
inline double power(double x) { return x*power<N-1>(x); }

template<>
inline double power<1>(double x) { return x; }

Now power<3>(x) is exactly equivalent to x*x*x;

You can further improve this function to compute x^4 as t=x*x;
result=t*t; i.e. with 2 multiplications instead of 3. If you want this
to work for any integer power (e.g x^6 = (x^2)^3) you must use recursive
function calls. But functions that call themselves cannot be inlined
unless the argument that changes during subsequent calls is a template
parameter.

I hope this example sheds some light on the usefulness of template
metaprogramming.

-- Szabolcs
Oct 9 '06 #3
I wrote a simple example of how to do a dot product using template
expressions. The following is optimised to a single assignment
expression.

template<typename _Value>
struct Vector
{
_Value _value;
};

template<typename _Vectorstruct VectorDotProd {};

template<typename _Type, int _Length>
struct VectorDotProd<Vector<_Type[_Length]
{
typedef Vector<_Type[_Length]_Vector;

__inline static float Apply(_Vector const & vector0,
_Vector const & vector1)
{
return Impl<_Type, _Length-1>::Apply(vector0, vector1);
}

template<typename _Type, int _Index>
struct Impl
{
__inline static float Apply(_Vector const & vector0,
_Vector const & vector1)
{
return vector0._value[_Index] * vector1._value[_Index]
+ Impl<_Type, _Index-1>::Apply(vector0, vector1);
}
};

template<typename _Type>
struct Impl<_Type, 0>
{
__inline static float Apply(_Vector const & vector0,
_Vector const & vector1)
{
return vector0._value[0] * vector1._value[0];
}
};

};

int main()
{
typedef Vector<float[3]Vector3f;
Vector3f v0 = {1.0f, 2.0f, 3.0f};
Vector3f v1 = {1.0f, 2.0f, 3.0f};

float result = VectorDotProd<Vector3f>::Apply(v0, v1);
_RPTF1(_CRT_WARN, "v0.v1 = %f\n", result);

printf("%f\n", result);

return 0;
}

Oct 9 '06 #4

Szabolcs Horvát wrote:
Jon Rea wrote:
double Square( double d )
{
return d * d;
}

and use it like this:

int main()
{
double answer = Square( 4.0 );
}
The compiler will optimize away the call to Square() if Square() is an
inline function. Some optimizing compilers (such as g++ with the -O3
option) can inline functions automatically.

Template metaprogramming is another thing: it allows to automatically
generate specialized (and thus efficient) code. E.g., if you want to
create a function that computes integer powers, you could use a for loop:

double power(int i, double x) {
double res = 1.0
for (; i 0; i--)
res *= x;
return res;
}

The compiler cannot optimize a call to power(3,x) to x*x*x. But you can
achieve this using the following function:
Do not underestimate modern compilers. g++ on -O3 is quite capable of
turning "power(3,d)" into "d*d*d". (I saw this by running
-fdump-tree-all, a command which shows the internal structure of the
code as the compiler compiles it). Of course templates are still
useful, but I consider them more useful for writing different functions
for different types and avoiding virtual functions, not for forcing
optimisers to do things they can often do by themselves.

Oct 9 '06 #5
Szabolcs Horvát wrote:
Jon Rea wrote:
>double Square( double d )
{
return d * d;
}

and use it like this:

int main()
{
double answer = Square( 4.0 );
}

I always assumed that the compiler is cleaver enough to decide that the
function call is not needed and just set 'answer' to 16 in the compiled
machine code. If that is the case, is the use of simple meta templates
irrelevent with modern compilers (esp. see 'Temporary variables' in the
example posted URL above).

The compiler will optimize away the call to Square() if Square() is an
inline function. Some optimizing compilers (such as g++ with the -O3
option) can inline functions automatically.
However, the function's code must be known in the translation unit that it
is used in, which usually means that you have to define it in the header
instead of doing the usual separation interface/implementation.
Template metaprogramming is another thing: it allows to automatically
generate specialized (and thus efficient) code. E.g., if you want to
create a function that computes integer powers, you could use a for loop:

double power(int i, double x) {
double res = 1.0
for (; i 0; i--)
res *= x;
return res;
}

The compiler cannot optimize a call to power(3,x) to x*x*x.
Well, you'd be surprised what kinds of optimzations compilers are capable
of.
Oct 9 '06 #6
ri*********@yahoo.co.uk wrote:
I wrote a simple example of how to do a dot product using template
expressions. The following is optimised to a single assignment
expression.

template<typename _Value>
struct Vector
{
_Value _value;
};
The identifier _Value is reserved to the implementation per 17.4.3.1.2,
and therefore your program will exhibit undefined behavior. It can do
anything.

[remainder of code redacted]
Oct 9 '06 #7
Szabolcs Horvát wrote:
template<int N>
inline double power(double x) { return x*power<N-1>(x); }

template<>
inline double power<1>(double x) { return x; }
As a side note, n to the 0 power is 1, so it would seem to be more
correct to specialize for N=0:

template<>
inline double power<0>(double) { return 1.0; }

Given this, The specialization for N=1 might still be useful, or might
not be.
Nate
Oct 9 '06 #8
Azumanga wrote:
>
Do not underestimate modern compilers. g++ on -O3 is quite capable of
turning "power(3,d)" into "d*d*d". (I saw this by running
-fdump-tree-all, a command which shows the internal structure of the
code as the compiler compiles it). Of course templates are still
useful, but I consider them more useful for writing different functions
for different types and avoiding virtual functions, not for forcing
optimisers to do things they can often do by themselves.
Wow, I am really amazed! I checked the assembly output and it really
does compute it at compile time.

However, the optimizer is still not smart enough to turn x*x*x*x into
(x^2)^2, nor can it optimize away a function that implements this using
recursion. But you can do it with templates (see attached code). This
way C++'s integer power calculation can be just as efficient as FORTRAN's.

According to http://osl.iu.edu/~tveldhui/papers/techniques/ , section
1.9, these techniques can also be used to eliminate temporaries when
e.g. adding to vectors 'a' and 'b' and make 'c=a+b;' store the result
directly into 'c', without the + operator creating and intermediate
object which in turn would be copied into 'c'.
See http://www.oonumerics.org/blitz/

Performance if often important when you are doing physics, like Jon.

I admit that these techniques can be really ugly and confusing, at least
I got really confused when trying to implement similar things (and gave
up). But they are also fascinating.

---

template<int N>
inline double power(double x) {
if (N%2 == 0)
return power<2>(power<N/2>(x));
if (N%3 == 0)
return power<3>(power<N/3>(x));
return x*power<N-1>(x);
}

template<>
inline double power<1>(double x) { return x; }

template<>
inline double power<2>(double x) { return x*x; }

template<>
inline double power<3>(double x) { return x*x*x; }
Oct 9 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Ingo Nolden | last post by:
Hi, I want to write a template class that holds another class that uses the same template. This recursion should stop after a predefined number. I think it's either impossible or easy, but I...
2
by: Ganesh | last post by:
I am not sure if the question is relevant to this group. Is there a proof that template metaprogramming is Turing-complete? Is the proof trivial - just replace all the template instantiaion with...
8
by: Tjerk Wolterink | last post by:
I have xml inpput like this: <meta:empty/> And xsl like this: <xsl:template match="meta:empty">A</xsl:template> <xsl:template match="//meta:*">B</xsl:template>
5
by: Jon Rea | last post by:
I work with molecular simulations. In a normal infinate space simulation, a particle can occupy any cartesian position in space. If i want the distance between two particles in a system I can...
35
by: Steven T. Hatton | last post by:
Perhaps I'm just a bit frustrated, and I will soon realize the clear truth of the matter, but right now I have some serious misgivings about the value of investing a lot of time and effort into...
2
by: adrian.hawryluk | last post by:
Hi everyone, I've been using templates for a while, but I'm not at full power yet (knowledge=power) ;). Does anyone know where I can get information on this 'new' template usage? template<a...
7
by: Kevin | last post by:
I'm creating a template to support state machines. In doing so, I need to pass an enumeration for the number of transitions and a non type parameter for the range of the enum (to allow me to...
3
by: stdlib99 | last post by:
Hi, I have a simple question regarding templates and meta programming. I am going to try and work my way through the C++ Template Metaprogramming, a book by David Abrahams and Aleksey...
2
by: Clyde | last post by:
Hi, what i'm trying to do is: /////////////// Code Start template <class TType, int* p = 0> class Template { public:
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shćllîpôpď 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.