C++: Optimizations made on wrapped methods that are trivial - c++

When I write wrapper classes, a lot of the methods take the following form:
class Wrapper{
public:
vec3 getPos(){ return m_position.get(); }
void setPos(vec3 pos){ m_position.set(pos); }
private:
ThingGettingWrapped m_position;
}
}
I was curious however, will getPos() and setPos() incur overhead, or are modern compilers smart enough to optimize the delegation away so wrapper.set/get() is equivalent to wrapper.m_thingWrapped.set/get()?
(I know the methods are inlined in my example, but assume they are not explicitly inlined and defined separately)

An optimizer can expand the call inline in which case there is no overhead for the extra call.
A wrapper like that can incur overhead if the call is not expanded inline.
Optimizers of modern compilers do inline expansion.
assume they are not explicitly inlined and defined separately
There will be (small) overhead unless the optimizer can expand the call inline. You can guarantee the ability to inline by calling the function in the same translation unit where it was defined. Defining the function inline - like you did in your example - enables and enforces this for all translation units because inline functions are defined in all of them. Another way to allow inline expansion across translation units is LTO.
A function is not required to be inline in order for it to be expandable inline and an optimizer is not required to inline-expand all calls to inline functions. A function that is inline will always be expandable inline. A function that is not inline may be expandable in some case, but not always.

These functions will get inlined by the compiler as long as some simple rules are followed:
They are not virtual (they aren't in your case, but could be in some other place) - compiler often can't inline virtual functions - because it would render the whole idea of virtual functions useless.
The actual implementation of the function is available to the compiler during the compilation of the source calling getPos. Again, it would not be possible to compile the example code, but you could declare getPos and setPos as member functions without giving them a body in the class, in which case the compiler won't (necessarily) be able to inline them. [1]
[1] Compilers that support Link Time Optimisation (LTO) or Whole Program Optimisation as some compiler vendors like to call it can inline functions even if the source is not available - this is because final code-generation isn't done until later, so a half-compiled version of the source is stored in the object file. In my experience, LTO is not used for most projects.

Related

Using the non-virtual-interface idiom, can/will my non-virtual function be inlined ?

I recently decided to use the non-virtual interface idiom (NVI) to design an interface in C++, mostly for the purpose of using a parameter with a default value (thus avoiding problems caused by the fact that default parameters are statically bound).
I came with a rather trivial declaration for my class, looking like this :
class Interface{
public:
void func(Parameter p = 0);
virtual ~Interface();
private:
virtual void doFunc(Parameter p)=0;
};
void Interface::func(Parameter p){ doFunc(p); }
Interface::~Interface() {}
I know that providing the function body in a header automatically mark a function as candidate for inlining (though I don't know if placing the definition outside of the class will prevent that). I also know that virtual function aren't inlined for obvious reasons (we don't know which function will be called at runtime, so we can't replace calls by the function's body obviously).
Then, in this case, will func() be marked candidate for inlining ? It isn't a virtual function, but still calls a virtual function. Does it make it inline-able ?
Extra question: would it be worth it ? The body consist of only one statement.
Note that this question is quite rather for learning about it rather than searching optimization everywhere. I know that this function will be called only a few time (well, for now, so might as well be prudent as to how the program evolves), and that inlining would be quite superfluous and not the main concern about my program's performance.
Thanks !
I know that providing the function body in a header automatically mark a function as candidate for inlining
More or less; but you do that by providing the function body in a class definition, or by explicitly declaring it inline if it's in a header. Otherwise, the function is subject to the One Definition Rule, and you'll get errors if you include the header in more than one translation unit.
Note that this doesn't force the compiler to inline all calls to the function; providing the definition in a header just allows it to inline it in any translation unit that includes the header, if it thinks it's worth it. Also, some compilers can perform "whole program optimisation", and inline functions even when a definition is not available at the call site.
Then, in this case, will func() be marked candidate for inlining ? It isn't a virtual function, but still calls a virtual function. Does it make it inline-able ?
Yes, all functions are candidates for inlining. If they call themselves, then obviously you couldn't inline all the calls; nor if the function isn't known at compile time (e.g. because it must be called virtually, or through a function pointer). In this case, inlining the function would replace the direct call to func() with a virtual call to doFunc().
Note that sometimes virtual calls can be inlined, if the dynamic type is known at compile time. For example:
struct MyImplementation : Interface {/*whatever*/};
MyImplementation thing;
thing.func(); // Known to be MyImplementation, func and doFunc can be inlined
Extra question: would it be worth it ?
That depends on what "it" is. If you mean compile time then, as long as the function remains short, you might get some benefit (possibly significant, if the function is called many times) for negligible cost. If you mean the cost of spending time choosing where to put it, then probably not; just put it wherever's most convenient.

Implicit inline virtual function implemented in header

Writing a function in a .h file and its implementation right after (implicit inline), while using the virtual keyword:
virtual void g(){cout<<"is Inline?"};
Is the virtual functionality meaningless because the function is implemented in the .h?
Is this considered to be an inline?
Is the virtual functionality meaningless because the function is implemented in the .h?
No. virtual and inline are completely independent concepts.
virtual means that the function to call is chosen, at run-time if necessary, according to the dynamic type of the object it's invoked on.
inline means that you're allowed to define the function in more than one translation unit, and must define it in any translation unit that uses it. This is necessary (for some compilers) to allow the function to be inlined, but does not force all calls to be inlined. In particular, virtual calls usually won't be inlined (unless the dynamic type can be determined at compile time), so virtual will certainly retain its meaning here.
Is this considered to be an inline?
Yes, but (as mentioned above) that does not mean that all calls will be inlined.
Is the virtual functionality meaningless because the function is
implemented in the .h?
Nope. No reason to feel so. Header file is preprocessed and copy-pasted wherever it's included. So ultimately it's as good as implementing your g() in whatever .cpp file.
Is this considered to be an inline?
Yes. But here the inline doesn't mean usual interpretation of replacing function call with its content. virtual function resolution happens at runtime, so that can definitely not be inlined in that (macro style) way.
It means, that compiler guarantees to generate only 1 definition for all translation (.cpp file) units. Thus linker will not complain about multiple definition errors.
If you declare your function virtual, it is virtual, period. But, since virtual functions are usually selected at runtime, usually the compiler will not be able to inline them. If you call the function on an object, the compiler may inline it, since the call can be resolved at compile time. But it won't be able to inline a call through a reference or pointer, since it cannot resolve the dynamic type at compile time.
Take into account that neither the inline keyword not the implicit inlining here are mandatory for the compiler; they are just suggestions. But the virtual keyword is mandatory.

Inline functions in c++ - conditions

Under What condition an inline function ceases to be an inline function and acts as any other function?
The Myth:
inline is just a suggestion which a compiler may or may not abide to. A good compiler will anyways do what needs to be done.
The Truth:
inline usually indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Under What condition an inline function ceases to be an inline function and acts as any other function?
Given the quoted fact there is a deeper context to this question.
When you declare a function as static inline function, the function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
The static keyword on the function forces the inline function to have an internal linkage.(inline functions have external linkage)
Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these ).
It's at the discretion of the compiler.
But some cases just can't be inlined, like:
Recursive functions
Functions whose address is referenced somewhere
Virtual functions (there are some exceptions thought)
That depends on the compiler optimization.
Different compilers have different rules to make the code more efficient. But if you declare a function as inline, the compiler tends to respect your decision as long as none of it's rules says different.
Remember that the compiler can change completely the execution path of a method. For example, consider the next situation:
int MyClass::getValue()
{
return someVariable;
}
At compile time, there is little difference between declaring this kind of function as inline or not. Probably the compiler will make the attribute partially public and code:
myInstance->getValue()
as
myInstance->someVariable
So it's more an aesthetical decision in most cases.

C++ - avoiding the implicit inlining of a function defined in the class definition

In my implementation files (.cc files), I often find that it's convenient to define member functions in class definitions (such as the functions of a Pimpl class). For example:
struct X::Impl {
void DoSomething() {
...
}
};
instead of
struct X::Impl {
void DoSomething();
};
void X::Impl::DoSomething() {
...
}
I think this is preferable to implementing the function outside of the class definition for several reasons. It enhances readability and facilitates the practice of keeping methods small (by making it easy to add them). The code is also easier to maintain since you never have to update method declarations.
The only downside I see is that methods defined in the class declaration are implicitly inlined, which is not usually desirable because of the increase in the size of the object code.
My questions are:
Do I have this right? Are there other downsides to this practice that I'm missing?
Is the implicit inlining something to worry about? Is the compiler smart enough to reject my implicit request to inline methods that shouldn't be inlined?
Is it possible (via compiler extensions or otherwise) to declare that a method defined in the class definition not be inlined?
The simple answer is that you should not care. Member functions defined within the class definition are implicitly inline, but that does not mean that they are inlined (i.e. the code need not be inlined at the place of call).
Compiler implementors have dedicated quite a bit of time and resources to come up with heuristics that determine whether actual inlining should be done or not, based on the size of the function, the complexity and whether it can be inlined at all or not (a recursive function cannot be inlined[*]). The compiler has more information on the generated code and the architecture in which it will run than most of us have. Trust it, then if you feel that there might be an issue, profile, and if profiling indicates that you should change the code, do it, but make an informed decision after the fact.
If you want to verify whether the function has actually be inlined or not, you can look at the assembly and check whether there are calls to the function or the code was really inlined.
[*] If the compiler can transform the recursion into iteration, as is the case in tail recursion, then the transformed function could be theoretically be inlined. But then, functions with loops have lesser probabilities of being inlined anyway...
I don't know portable way of preventing inlining, but with GCC you can use attribute. For example:
struct X::Impl {
void DoSomething() __attribute__((noinline)) {
...
}
};
Add up all the CPU time that will ever be saved by your inlining choices. Spend less than that of your own on them. Linear pathlength worries are for paths handling now trillions of executions a day. Four billion is near enough a second out of L1. 250 times that isn't five minutes. If nobody's complaining about performance, your and your compiler's choices are at least playing in the right league.
Opinions on readability differ widely. It's your audience's opinion that matters.
Generally, the compiler will inline whatever it pleases, and it won't pay too much attention to any inline keywords given by the programmer. inline is usually treated more or less the same as static.
For example, a recursive function can usually not be completely inlined (the function body you'd inline will contain again a call that should be inlined). To test the behavior of your specific compiler, you could for example define a class like this:
class Fib {
public:
int calc(int i);
};
int Fib::calc(int i) {
if (i > 1)
return calc(i-1) + calc(i-2);
return 1;
}
With this definition, a sample program like the following would not be compilable in reasonable time or size if the compiler would feel obligated to inline all calls to calc:
#include "tst.hpp"
#include <iostream>
int main() {
Fib f;
std::cout << f.calc(1000) << std::endl;
};
So you can test you compilers behavior by compiling this program. If compilation succeeds, the compiler didn't inline all calls to Fib::calc.

What are the inlining rules within C++ classes?

From what I read somewhere long time ago, it seems that if you want class member function to be inlined during the compilation phase, the function has to be defined inside class declaration block.
But this has a downside of a detail leak. IMHO, other programmers should only see class interface when opening .h file.
Is the first statement still true in modern C++, was it ever? Is there a way to force inlining for functions that are declared, preferably in another file altogether?
Is it generally better to keep short member functions inside class declaration block, or not?
It seems that if you want class member function to be inlined during the compilation phase, the function has to be defined inside class declaration block.
That is not really true. A function that is defined inside the class definition is implicitly marked as inline. But you don't need to defined the function inside the class for it to be inline, you can explicitly request it:
struct X {
void f();
};
inline void f() {}
The inline keyword on the other hand, does not mean that the function will be inlined, but rather that it can be defined in multiple translation units, that is, if multiple translation units include the same header that contains that definition, the linker will not fail with a multiple definition error.
Now, on actual inlining, the compiler can decide to inline or not any function, regardless of whether the function is declared as inline provided that it sees the definition of that function (the code that it will inline), which is the reason why in general functions that are meant to be inlined should be defined in the header (either inside the class definition or marked inline outside.
Additionally, newer toolchains can perform whole program optimization or other link time optimizations, by which the linker can also decide that a function should be inlined. In this case, the function definition needs not be visible at the call site, so it could be defined inside the .cpp file. But if you really want the function to be inlined it is better not to depend on this feature and just define the function in the header.
Q: Is there a way to force inlining for functions?
A: No
No matter how you designate a function as inline, it is a request that
the compiler is allowed to ignore: it might inline-expand some, all,
or none of the calls to an inline function.
Q: What are the inlining rules within C++ classes?
Inline member functions in C++
As far as Standard C++ is concerned, a inline function must be defined
in every translation unit in which it is used
...
This is different from non-inline functions which must be defined only
once in an entire program (one-definition-rule)...
For member-functions, if you define your function in the class, it is
implicitly inline. And because it appears in the header, the rule that
it has to be defined in every translation unit in which it is used is
automatically satisfied.
Here is a great FAQ (one that's more "practical" than "pedantic"):
http://www.parashift.com/c++-faq-lite/inline-functions.html
Is the first statement still true in modern C++, was it ever?
As David explained, there's the inline keyword as well. It can be ignored, as Paul stated.
Is there a way to force inlining for functions that are declared,
preferably in another file altogether?
Probably by configuring your compiler. It might be doing some inling behind your back anyway. Eg. gcc has -finline-functions etc. that will be switched on for certain optimisation levels
Is it generally better to keep short member functions inside class declaration block, or no?
Up to you. Be aware though that if you have an inline method used lots of times, then you can be increasing the size of your object files, and so potentially bloat the size of what you're building and maybe slow it down.
FWIW I only tend to put implementations in header files out of laziness :)