public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* c++ function templates and memory hogging
@ 2008-12-10 18:52 Guido Loupias
  2008-12-10 19:27 ` Mojmir Svoboda
  0 siblings, 1 reply; 4+ messages in thread
From: Guido Loupias @ 2008-12-10 18:52 UTC (permalink / raw)
  To: gcc-help

Hi,

Why does the following behavior occur?

I have 2 naive implementations of fibonacci through function templates.
The first one has no problem compiling fib<46>(). However the second one starts 
eating significant memory when N > 23. It's gradual (seems to be exponential 
with regard to N) but when N = 27 the compilation process consumes about a gigabyte.

This happens when compiling with -O1 or higher.

(1)
template<int N>
inline int fib() {
     static const int n = fib<N-1>() + fib<N-2>();
     return n;
}
template<>
inline int fib<0>() {
     return 0;
}
template<>
inline int fib<1>() {
     return 1;
}

(2)
template<int N>
inline int fib() {
     return fib<N-1>() + fib<N-2>();
}
template<>
inline int fib<0>() {
     return 0;
}
template<>
inline int fib<1>() {
     return 1;
}

Regards,
Guido

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: c++ function templates and memory hogging
  2008-12-10 18:52 c++ function templates and memory hogging Guido Loupias
@ 2008-12-10 19:27 ` Mojmir Svoboda
  2008-12-10 20:54   ` Guido Loupias
  0 siblings, 1 reply; 4+ messages in thread
From: Mojmir Svoboda @ 2008-12-10 19:27 UTC (permalink / raw)
  To: gcc-help

* Guido Loupias <guidoloupias@gmail.com> [2008-12-10 19:51:33 +0100]:

> Why does the following behavior occur?
>
> I have 2 naive implementations of fibonacci through function templates.
> The first one has no problem compiling fib<46>(). However the second one 
> starts eating significant memory when N > 23. It's gradual (seems to be 
> exponential with regard to N) but when N = 27 the compilation process 
> consumes about a gigabyte.

i do not attempt to answer your problem, but i thought traditional way to do
compile-time computation was like:

template<int N>
struct fib {
    static int const n = fib<N-1>::n + fib<N-2>::n;
};
template<>
struct fib<0> {
    static int const n = 0;
};
template<>
struct fib<1> {
    static int const n = 1;
};

(or using enums) which behaves much better for me. local gurus will probably 
explain best why..

best regards,
mojmir

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: c++ function templates and memory hogging
  2008-12-10 19:27 ` Mojmir Svoboda
@ 2008-12-10 20:54   ` Guido Loupias
  2008-12-10 21:13     ` me22
  0 siblings, 1 reply; 4+ messages in thread
From: Guido Loupias @ 2008-12-10 20:54 UTC (permalink / raw)
  To: gcc-help

Mojmir Svoboda schreef:
> i do not attempt to answer your problem, but i thought traditional way to do
> compile-time computation was like:
> 
> template<int N>
> struct fib {
>     static int const n = fib<N-1>::n + fib<N-2>::n;
> };
> template<>
> struct fib<0> {
>     static int const n = 0;
> };
> template<>
> struct fib<1> {
>     static int const n = 1;
> };
> 
> (or using enums) which behaves much better for me. local gurus will probably 
> explain best why..
> 
> best regards,
> mojmir

You're right. Judging from the resulting object file it's much cleaner and it 
also works for large values of N. Still I wonder why the second function 
template version of the algorithm in my previous e-mail behaves the way it does. 
Perhaps it's doing computation on 2^N integers?

Regards,
Guido

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: c++ function templates and memory hogging
  2008-12-10 20:54   ` Guido Loupias
@ 2008-12-10 21:13     ` me22
  0 siblings, 0 replies; 4+ messages in thread
From: me22 @ 2008-12-10 21:13 UTC (permalink / raw)
  To: Guido Loupias; +Cc: gcc-help

On Wed, Dec 10, 2008 at 15:53, Guido Loupias <guidoloupias@gmail.com> wrote:
> Mojmir Svoboda schreef:
>>
>> i do not attempt to answer your problem, but i thought traditional way to
>> do
>> compile-time computation was like:
>>
>> template<int N>
>> struct fib {
>>    static int const n = fib<N-1>::n + fib<N-2>::n;
>> };
>> template<>
>> struct fib<0> {
>>    static int const n = 0;
>> };
>> template<>
>> struct fib<1> {
>>    static int const n = 1;
>> };
>>
>> (or using enums) which behaves much better for me. local gurus will
>> probably explain best why..
>>
>> best regards,
>> mojmir
>
> You're right. Judging from the resulting object file it's much cleaner and
> it also works for large values of N. Still I wonder why the second function
> template version of the algorithm in my previous e-mail behaves the way it
> does. Perhaps it's doing computation on 2^N integers?
>

I don't know how function-scope statics are handled, but if they were
initialized separately from running them (somehow), then each function
would only ever be "return a static" in the first case, but in the
second it would likely inline all the function calls, resulting in an
addition with O(fib(n)) terms.  If the static is done inside the
function, then the inliner might just be refusing to inline it after a
certain point, as the function would be getting large quickly.

Regardless, Mojmir Svoboda's is certainly a better approach.  The
reason being that the results of the computation are also memoised,
rather than just the declarations, as they're static constants inside
the type, so there's no "call graph" built at all, which is the part
with O(fib(n)) behaviour.

HTH,
~ Scott

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-12-10 21:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-10 18:52 c++ function templates and memory hogging Guido Loupias
2008-12-10 19:27 ` Mojmir Svoboda
2008-12-10 20:54   ` Guido Loupias
2008-12-10 21:13     ` me22

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).