How to use template to improve efficiency?

S

shuisheng

Dear All,

I have the following example and try to improve its efficiency.

#include<iostream>
using namespace std;

double a[] = {1.1, 2, 3, 4, 5, 6, 7, 8, 9.2};

template<double p[], int n>
inline
double Sum()
{
double result = 0;
for (int i = 0; i < n; ++i)
{
result += a;
}
return result;
}

int main()
{
cout << Sum<a, 9>();
return 0;
}

I hope the sum result can be calculated at compilation. But it isn't.
I look into the diassembly code, I see several fadd operations (the
loop is unrolled by the compiler). Any way can make the final sum
result is calculated at the compilation.

Thank you very much for your kind help!

Shuisheng
 
S

shuisheng

Thank you for your response. Please note that a is an array of
constant double numbers. I think that is why make it all be done at
compilation time really hard. Bust since the array elements are
constant, I think there should be a way to do it at compilation time.

I appreciate your kind help!!!

Shuisheng

shuisheng said:
I have the following example and try to improve its efficiency.
#include<iostream>
using namespace std;
double a[] = {1.1, 2, 3, 4, 5, 6, 7, 8, 9.2};
template<double p[], int n>
inline
double Sum()
{
  double result = 0;
  for (int i = 0; i < n; ++i)
  {
    result += a;
  }
  return result;
}

int main()
{
  cout << Sum<a, 9>();
  return 0;
}
I hope the sum result can be calculated  at compilation. But it isn't..
I look into the diassembly code, I see several fadd operations (the
loop is unrolled by the compiler). Any way can make the final sum
result is calculated at the compilation.

A way to make it all be done at compilation time is to create a
recursive template.  You know, you can basically do the addition in a
recursive function:

     int sum(int array[], int n)
     {
        if (n > 1)
            return array[n-1] + sum(array, n-1);
        else
            return array[0];
     }

Now, put it in the form of a template, by means of defining a
specialization (no 'if's allowed).  Remember that

    template<int K> int blah();

can be specialized for any particular K, like so

    template<> int blah<42>() {  ... }

The idiomatic form of calculating the factorial is

    template<int N> int factorial() {
        return N*factorial<N-1>();
    }

    // along with the specialization
    template<> int factorial<0> {
        return 1;
    }

Enough to go for you homework?  Call us back if you get stuck again.

V
 
J

Jonathan Lee

You cannot execute return statements at compile time either so what you
suggest is not the answer to the OP.

/Leigh

You can get around this by using a struct with a static const
member. Something like

template<unsigned long N>
struct countbits {
static const unsigned nbits = countbits< (N >> 1) >::nbits + 1;
};

template<>
struct countbits<0> {
static const unsigned nbits = 0;
};

#include <iostream>

int main() {
std::cout << countbits<987397UL>::nbits << std::endl;
}

You could probably adapt the idea for summing an array like
the OP wanted.

--Jonathan
 
T

tonydee

double a[] = {1.1, 2, 3, 4, 5, 6, 7, 8, 9.2};

template<double p[], int n>
inline double Sum()
{
  double result = 0;
  for (int i = 0; i < n; ++i)
    result += a;
  return result;
}

int main()
{
  cout << Sum<a, 9>();
}

I hope the sum result can be calculated  at compilation. But it isn't.


Given only...
double a[] = {1.1, 2, 3, 4, 5, 6, 7, 8, 9.2};

....there is no way to guarantee a compiler calculates the sum of this
array at compile time. Note: C++ doesn't allow floating point values
as template parameters, so techniques mentioned elsewhere in thread
aren't applicable to this exact problem. You can't index into the
array either. If you know the exact number of arguments, you can
create a preprocessor macro to output the array and a constant sum,
but that must replace the "double a[] = {...}" code, rather than being
coded afterwards: not particularly useful. You might consider
generating the sum as a small build/run code-generation step in your
build process....

Cheers,
Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top