Is there a special reason to use inline before template functions?

Hi, in boost, many template functions (but not all) use inline. (Example from boost/accumulators/framework/accumulator_set.hpp that uses inline: template<typename Args> inline accumulator_visitor<Args> const make_accumulator_visitor(Args const &args) { return accumulator_visitor<Args>(args); } Example from boost/algorithm/minmax.hpp hat doesn't use inline: template <typename T> tuple< T const&, T const& > minmax(T const& a, T const& b) { return (b<a) ? make_tuple(cref(b),cref(a)) : make_tuple(cref(a),cref(b)); } ) Is there a special reason why inline is used for template functions? I would expect that current compilers know better when inlining a function provides a benefit than the programmer. So I guess there is a better reason for using the inline keyword before template function than just speculative performance optimization, but I can't figure it out. Can anybody help me? Most libs only prepend inline before template functions, but ublas prepends nearly every member function with the macro "BOOST_UBLAS_INLINE", which expands to "inline". Is there a reason why ublas uses this macro? Regards, Thomas

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Michael Marcin wrote:
Thomas Klimpel wrote:
I would expect that current compilers know better when inlining a function provides a benefit than the programmer.
They don't.
This is really sorta off-topic here, but I find that statement hard to believe. Can you in any way substantiate that argument? I personally *never* use the keyword inline, since the compiler is free to ignore it, and may choose to inline functions I have not declared inline. What little I do know about compiler internals would lead me to believe that they could - and should - indeed know better than the programmer when it makes sense to inline a function. To complicate matters further, inlining a given function may make sense in certain contexts but not others. I believe Herb Sutter has given the subject thorough treatment some years gone. Nothing I have experienced has caused me to doubt his words in this matter. /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFJPWfNk1tAOprY6QERAuAWAKCO9QOXYrCMYq9mYeJzd+TJKVf7AQCglgcO Iz4TY9G+lO785sIqqdbAW9M= =lLDa -----END PGP SIGNATURE-----

on Mon Dec 08 2008, Brian Ravnsgaard Riis <brian-AT-ravnsgaard.net> wrote:
Michael Marcin wrote:
Thomas Klimpel wrote:
I would expect that current compilers know better when inlining a function provides a benefit than the programmer.
They don't.
This is really sorta off-topic here, but I find that statement hard to believe. Can you in any way substantiate that argument? I personally *never* use the keyword inline, since the compiler is free to ignore it, and may choose to inline functions I have not declared inline.
What little I do know about compiler internals would lead me to believe that they could - and should - indeed know better than the programmer when it makes sense to inline a function.
It has been known to be a problem for people using Visual C++ that they couldn't get it to inline the functions that really needed to be inlined without using a proprietary __forceinline (or some such) extension.
To complicate matters further, inlining a given function may make sense in certain contexts but not others. I believe Herb Sutter has given the subject thorough treatment some years gone. Nothing I have experienced has caused me to doubt his words in this matter.
You should talk to more people who care about high performance. Most of the time, you probably want the compiler to choose, but sometimes you really need the control. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On 12/8/08, Brian Ravnsgaard Riis <brian@ravnsgaard.net> wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Michael Marcin wrote:
Thomas Klimpel wrote:
I would expect that current compilers know better when inlining a function provides a benefit than the programmer.
They don't.
This is really sorta off-topic here, but I find that statement hard to believe. Can you in any way substantiate that argument? I personally *never* use the keyword inline, since the compiler is free to ignore it, and may choose to inline functions I have not declared inline.
What little I do know about compiler internals would lead me to believe that they could - and should - indeed know better than the programmer when it makes sense to inline a function.
To complicate matters further, inlining a given function may make sense in certain contexts but not others. I believe Herb Sutter has given the subject thorough treatment some years gone. Nothing I have experienced has caused me to doubt his words in this matter.
The compiler is free to not inline the contents of the function, but inline also changes the resolution rules. It causes it to be defined in each compliation unit (in C you would use static to change the resolution rules between objects). If you define a function in a header, it should be inlined to avoid linker errors. If you have function defined in a class defination, it is inlined even without the keyword. We use inlining in release builds were things like getters (and, of course, templates class member functions that are defined outside of class declaration) are included in from header files and in debug build get built into the object files. It allows for more than just inlining the body of the function, if you have chains of getters that are defined to where the compiler can see them, they get to all be optimized away.

Brian Ravnsgaard Riis wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Michael Marcin wrote:
Thomas Klimpel wrote:
I would expect that current compilers know better when inlining a function provides a benefit than the programmer. They don't.
This is really sorta off-topic here, but I find that statement hard to believe. Can you in any way substantiate that argument? I personally *never* use the keyword inline, since the compiler is free to ignore it, and may choose to inline functions I have not declared inline.
What little I do know about compiler internals would lead me to believe that they could - and should - indeed know better than the programmer when it makes sense to inline a function.
The compiler can know a lot but it can't know how often code is called when calling the code is the result of data or user input.
To complicate matters further, inlining a given function may make sense in certain contexts but not others. I believe Herb Sutter has given the subject thorough treatment some years gone. Nothing I have experienced has caused me to doubt his words in this matter.
Inlining is a low level optimization and like all such optimizations they should only be done after the correct algorithms, abstractions, and representations are in place with the aid of profiling. That being said I worked on a embedded project that needed to render 3d in software in realtime. We made heavy use of boost, templates, classes, and metaprogramming. In the rendering code especially controlling which functions were expanded inline and which were function calls was the difference between having a product which could ship and one that was too slow to pass cert. Luckily we were able to give the compiler enough information to choose which functions to inline because the language gives us the tool to do so, the inline keyword. -- Michael Marcin

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Michael Marcin wrote:
Brian Ravnsgaard Riis wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Michael Marcin wrote:
Thomas Klimpel wrote:
I would expect that current compilers know better when inlining a function provides a benefit than the programmer. They don't.
This is really sorta off-topic here, but I find that statement hard to believe. Can you in any way substantiate that argument? I personally *never* use the keyword inline, since the compiler is free to ignore it, and may choose to inline functions I have not declared inline.
What little I do know about compiler internals would lead me to believe that they could - and should - indeed know better than the programmer when it makes sense to inline a function.
The compiler can know a lot but it can't know how often code is called when calling the code is the result of data or user input.
To complicate matters further, inlining a given function may make sense in certain contexts but not others. I believe Herb Sutter has given the subject thorough treatment some years gone. Nothing I have experienced has caused me to doubt his words in this matter.
Inlining is a low level optimization and like all such optimizations they should only be done after the correct algorithms, abstractions, and representations are in place with the aid of profiling.
Indeed. The compiler may still ignore it, though.
That being said I worked on a embedded project that needed to render 3d in software in realtime. We made heavy use of boost, templates, classes, and metaprogramming. In the rendering code especially controlling which functions were expanded inline and which were function calls was the difference between having a product which could ship and one that was too slow to pass cert. Luckily we were able to give the compiler enough information to choose which functions to inline because the language gives us the tool to do so, the inline keyword.
So, there was a good argument after all! :-D I was hoping you would come back with something more descriptive than "They don't." I think it was the terseness of it I frowned upon. Of course, after profiling, applying a hint to the compiler about inlining may indeed be in order. I still think it is a rare thing that you should second-guess your compiler, but I'll admit that it can have its uses. Actually, I think I would prefer inlining a specific function *call* if that were possible, not the function, but... Heading seriously off-topic here... Thanks for your replies, Dave, Jonathan and Michael. I got the "discussion" I was hoping for. :-) /Brian -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFJPsDPk1tAOprY6QERAuHUAKDNq00v+1nYEaoom/n23+GBbr2U8ACdFA5W 40tXjmdeNNkZACm78s3m76M= =qUM4 -----END PGP SIGNATURE-----

Brian Ravnsgaard Riis wrote:
So, there was a good argument after all! :-D I was hoping you would come back with something more descriptive than "They don't." I think it was the terseness of it I frowned upon.
No problem :)
Of course, after profiling, applying a hint to the compiler about inlining may indeed be in order. I still think it is a rare thing that you should second-guess your compiler, but I'll admit that it can have its uses. Actually, I think I would prefer inlining a specific function *call* if that were possible, not the function, but...
I've had to jump through hoops to achieve just that before. Basically I wrote a function I force to inline and then making a trivial function which I don't inline which forwards to the first function. Then I use the first function directly when I want the call inline and the second function when I don't want the code bloat. It is an ugly solution but it functioned.
Heading seriously off-topic here... Thanks for your replies, Dave, Jonathan and Michael. I got the "discussion" I was hoping for. :-)
HTH -- Michael Marcin

Thomas Klimpel wrote:
Hi,
in boost, many template functions (but not all) use inline.
Is there a special reason why inline is used for template functions? I would expect that current compilers know better when inlining a function provides a benefit than the programmer. So I guess there is a better reason for using the inline keyword before template function than just speculative performance optimization, but I can't figure it out. Can anybody help me?
To my understanding, template functions are no different from the regular (non-template) functions. If it's not marked up as inline, it is not inline, and compilers may not inline it unless some aggressive optimization is on (like -finline-functions on GCC or -Ob2 on MSVC, IIRC). However, one significant difference should be noted. Unlike regular functions, non-inline template functions do not cause linking errors if instantiated from different TUs. That's why the inline keyword is often simply forgotten when it actually should be there.
Most libs only prepend inline before template functions, but ublas prepends nearly every member function with the macro "BOOST_UBLAS_INLINE", which expands to "inline". Is there a reason why ublas uses this macro?
I didn't look at the code, but if these member functions are declared in the class definition, they are already inline and this keyword is not needed. If not, then this is probably to get rid of the aforementioned linking problems.

Andrey Semashev wrote:
I didn't look at the code, but if these member functions are declared in the class definition, they are already inline and this keyword is not needed.
Some compilers disable default inlining under certain configurations. GCC has -fno-default-inline for instance. Some libraries might explicitly put inline there to support these configurations. -- Michael Marcin

Michael Marcin wrote:
Andrey Semashev wrote:
I didn't look at the code, but if these member functions are declared in the class definition, they are already inline and this keyword is not needed.
Some compilers disable default inlining under certain configurations. GCC has -fno-default-inline for instance. Some libraries might explicitly put inline there to support these configurations.
Well, I guess the one who uses such configurations does so for a reason (i.e. he wants these functions *not* to be inline), so the keyword still doesn't make sense to me. Unless it works around some compiler bug...

Andrey Semashev wrote:
Some compilers disable default inlining under certain configurations. GCC has -fno-default-inline for instance. Some libraries might explicitly put inline there to support these configurations.
Well, I guess the one who uses such configurations does so for a reason (i.e. he wants these functions *not* to be inline), so the keyword still doesn't make sense to me. Unless it works around some compiler bug...
Thanks for the answers. So my conclusion is: - the inline keyword for template functions is only required for performance reasons. - My expectation that current compilers know better than me when to inline a function may be too optimistic. My problem is that some code in numeric-bindings uses the inline keyword for template functions quite inconsistently. I had hoped that the inline keyword itself is superfluous, so that I can simply remove it without any further thought. I will now try to use the inline keyword for obvious cases like simple forwarders, and remove it from more complex template functions where I'm unable to decide whether it is a good idea to inline the function. My reason for this is that I don't want to think too much about possible performance impact of inlining, but don't want to deviate too much from the common practice of other boost-libraries. Regards, Thomas

On Dec 7, 2008, at 6:48 PM, Thomas Klimpel wrote:
in boost, many template functions (but not all) use inline. (Example from boost/accumulators/framework/accumulator_set.hpp that uses inline: template<typename Args> inline accumulator_visitor<Args> const make_accumulator_visitor (Args const &args) { return accumulator_visitor<Args>(args); }
Example from boost/algorithm/minmax.hpp hat doesn't use inline: template <typename T> tuple< T const&, T const& > minmax(T const& a, T const& b) { return (b<a) ? make_tuple(cref(b),cref(a)) : make_tuple(cref (a),cref(b)); } )
Is there a special reason why inline is used for template functions? I would expect that current compilers know better when inlining a function provides a benefit than the programmer. So I guess there is a better reason for using the inline keyword before template function than just speculative performance optimization, but I can't figure it out. Can anybody help me?
Template stuff generally has to be defined in a header file ("export" notwithstanding). My guideline for "inline" is whether or not I would use for a particular function if that function had no template stuff about it. (In other words, would I leave it "inline" in a header or non-inline in a mandatory source file.)
Most libs only prepend inline before template functions, but ublas prepends nearly every member function with the macro "BOOST_UBLAS_INLINE", which expands to "inline". Is there a reason why ublas uses this macro?
-- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (7)
-
Andrey Semashev
-
Brian Ravnsgaard Riis
-
Daryle Walker
-
David Abrahams
-
Jonathan Brannan
-
Michael Marcin
-
Thomas Klimpel