473,387 Members | 1,579 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,387 software developers and data experts.

Disadvantage of using 'inline'

If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?
Nov 14 '05 #1
18 5003
In <fl*******************@read2.cgocable.net> "Method Man" <a@b.c> writes:
If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?


1. inline is not a portable feature of C.

2. There is no guarantee that inlining everything is going to speed up
your code. Larger executable means less efficient usage of the
processor cache.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #2
Method Man wrote:
If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?


Thoughtless inlining might easily cause code bloat, which will make your
program run _less_ efficiently.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #3
Greetings,

Dan Pop wrote:
In <fl*******************@read2.cgocable.net> "Method Man" <a@b.c> writes:

If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?

1. inline is not a portable feature of C.


Odd, I must be horribly misreading 6.7.4: Function specifiers
--
Kyle A. York
Sr. Subordinate Grunt, SC
Nov 14 '05 #4
kyle york <ky***@cisco.com> writes:
Greetings,
Dan Pop wrote:
In <fl*******************@read2.cgocable.net> "Method Man" <a@b.c> writes:
If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?

1. inline is not a portable feature of C.


Odd, I must be horribly misreading 6.7.4: Function specifiers


His point is that "inline" is a new feature in C99, not supported by
C90, and that C99 compilers are not yet widespread enough for code
that depends on C99-specific features to be considered portable.

On the other hand, many compilers that don't support all of C99 do
support inline (whether they do so in a way that's 100% compatible
with the C99 specification is another question).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5
Method Man wrote:
If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?


Disclaimer: Parts of this response may be platform-specific.

Actually, many compilers *do* aggressively inline small functions within
a module at high optimization levels, even if you don't explicitly ask
them to. For example, gcc does this at -O3 (which includes the flag
-finline-functions, the primary difference from -O2).

No good compiler will inline a large function, though, even if you ask
it to, not only because of the large space overhead in doing so but
because the purpose of inlining is to eliminate function call overhead,
and this is simply relatively insigificant if enough time is spent
inside the function called (even a small function with a long loop
doesn't benefit from inlining).

Placing the inline keyword on all static (module-local) functions is an
okay thing to do, if you trust your compiler; it'll figure out when not
to do it, although you can't take an inline function's address to call
it indirectly, and you'll look a bit silly. Trouble starts when you
attempt to export an inline function, though, and use it in multiple
modules. Such an inline function has to include its definition in every
module using it, usually via a header. If the compiler ends up not
inlining it, for whatever reason, this may result in a copy of its code
being placed in every module that uses it. Thus you should only export
small inline functions.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #6
Derrick Coetzee wrote:
...
Placing the inline keyword on all static (module-local) functions is an
okay thing to do, if you trust your compiler; it'll figure out when not
to do it, although you can't take an inline function's address to call
it indirectly, and you'll look a bit silly.
While it is true that an indirect call cannot be inlined (for obvious
reasons), there is absolutely no problem with taking an address of an
inline function. You seem to be mistaking two different things: inline
functions and inlined calls to functions.
Trouble starts when you
attempt to export an inline function, though, and use it in multiple
modules. Such an inline function has to include its definition in every
module using it, usually via a header. If the compiler ends up not
inlining it, for whatever reason, this may result in a copy of its code
being placed in every module that uses it. Thus you should only export
small inline functions.


That would be true in C++, but that's not necessarily true in C (C99).
An inline function with external linkage in C can have external
definition in addition to inline definition. The external definition can
be reached from other translation units (by non-inline calls, of course).

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #7
Method Man wrote:
If I don't care about the size of my executable or compile time,
is there any reason why I wouldn't want to inline every function in my code
to make the program run more efficient?


No.
You may find that you want to define than as "inline static"
in a header file so that you don't get "multiply defined references".

The idea behind inline functions is to encourage programmers
to decompose functions into smaller functions
and let the compiler "inline" them automatically
instead of inlining them manually.
This should result in code
that is easier to read, understand and maintain
while maximizing performance and efficiency.
Nov 14 '05 #8
"E. Robert Tisdale" wrote:
Method Man wrote:
If I don't care about the size of my executable or compile time,
is there any reason why I wouldn't want to inline every function
in my code to make the program run more efficient?
No.
You may find that you want to define than as "inline static"
in a header file so that you don't get "multiply defined references".


If the function is static there is no point in mentioning it in
any header file. Headers should be used solely to export things
from a compilation unit. Static functions are not accessible
outside the compilation unit.

The idea behind inline functions is to encourage programmers to
decompose functions into smaller functions and let the compiler
"inline" them automatically instead of inlining them manually.
This should result in code that is easier to read, understand and
maintain while maximizing performance and efficiency.


This is accurate.

--
"It is not a question of staying the course, but of changing
the course" - John Kerry, 2004-09-20
"Ask any boat owner the eventual result of continuing the
present course indefinitely" - C.B. Falconer, 2004-09-20
Nov 14 '05 #9
Da*****@cern.ch (Dan Pop) wrote in message news:<cj**********@sunnews.cern.ch>...
In <fl*******************@read2.cgocable.net> "Method Man" <a@b.c> writes:
If I don't care about the size of my executable or compile time, is there
any reason why I wouldn't want to inline every function in my code to make
the program run more efficient?


1. inline is not a portable feature of C.

2. There is no guarantee that inlining everything is going to speed up
your code. Larger executable means less efficient usage of the
processor cache.


A larger executable may mean less efficient usage of the processor
cache, but it may not. As an obvious example, judicious loop
unrolling (by the compiler) often causes larger code, but faster code.
Of course, everything in moderation: if you unroll too much you will
cause icache (or trace cache) thrashing because your working sets keep
pushing each other out. That's really the essence of what Dan was
getting at.

As usual, there's a bunch of competing factors. Inlining small,
frequently *called* functions may be beneficial because it eliminates
function call overhead and allows CSE and other optimizations to be
performed within the context of the caller. This could translate to
fewer branches, which reduces the likelihood of mispredicted branches,
which can be costly.

Now I just said small, frequently *called* functions, but I did not
mean frequently *used* functions, unless they're so small that
function call overhead is more than, or a significant percentage of,
their execution time. By frequently used functions, I mean the ones
you find sprinkled all over the code, but not typically in performance
sensitive areas. These are what you do not want to inline, because
the code bloat is not worth it.

One big problem is that your inline function looks like a function to
you, and in the source code, but not to the processor. Inline
functions will not cause a hot spot in the cache. They decrease
locality. If your program calls a frequently used inline function
twice reasonably near each other, for example, the second call will
*not* find the function already sitting in cache, ready to go.
Granted, hardware prefetch may cause this to be a moot point in some
cases, but then again, the hardware prefetch would then be fetching
something that should already be in the cache, and displacing
something else that may be beneficial.

So what can you inline? Well, the best functions to inline are the
ones that are used exactly once and are static. It's hard to go wrong
with that. With anything else, you need to profile your code and be
familiar with the relative costs your architecture imposes on you. As
always, when in doubt, check your compiler's assembly output. You may
be pleasantly surprised to find that your compiler is good at figuring
out which functions to inline for you, under certain optimization
levels. And if you religiously use static functions, as you should,
the compiler has a much easier time at doing just that.

If you're serious about code performance, you need to be familiar with
the applicable profiling tools and with the increasingly popular
profile driven optimization. Profile driven optimization gives the
compiler a much better idea of which branches are taken and which are
not, so that it can output the best possible assembly. Now when you
combine that with profiling and subsequent inlining and tweaking, you
have the possibility of some very well performing code. But you're
not going to get that by simply inlining everything, that's for sure.
Mark F. Haigh
mf*****@sbcglobal.net
Nov 14 '05 #10
On Fri, 24 Sep 2004 17:49:12 -0700, Andrey Tarasevich wrote:
Derrick Coetzee wrote:
...
Placing the inline keyword on all static (module-local) functions is an
okay thing to do, if you trust your compiler; it'll figure out when not
to do it, although you can't take an inline function's address to call
it indirectly, and you'll look a bit silly.


While it is true that an indirect call cannot be inlined (for obvious
reasons), there is absolutely no problem with taking an address of an
inline function. You seem to be mistaking two different things: inline
functions and inlined calls to functions.


This seems odd to me, too: If the function `should' be inlined (and,
therefore, have no independent existence), what is the rationale for
allowing programmers to take its address? Wouldn't that pretty much defeat
the purpose, by forcing the compiler to generate code for the function at
a specific location?

My point of reference isn't C++, but the C `register' keyword. It turns
out that C compilers are under no obligation to listen to the programmer
about which variables to try and place in registers (and on plenty of
machines, there are so few registers that tying one up is stupid), but the
compiler is obligated to act as if it had by disallowing the taking of the
address of a register-qualified variable.

Nov 14 '05 #11
Chris Barts wrote:
...
Placing the inline keyword on all static (module-local) functions is an
okay thing to do, if you trust your compiler; it'll figure out when not
to do it, although you can't take an inline function's address to call
it indirectly, and you'll look a bit silly.
While it is true that an indirect call cannot be inlined (for obvious
reasons), there is absolutely no problem with taking an address of an
inline function. You seem to be mistaking two different things: inline
functions and inlined calls to functions.


This seems odd to me, too: If the function `should' be inlined (and,
therefore, have no independent existence), what is the rationale for
allowing programmers to take its address?


Declaring a function as 'inline' never meant that is has no "independent
existence".

The decision to inline a call is made by the compiler on a per-call
basis. Nothing in the language specification says that a function should
be either always inlined or never inlined. This has never been the
intention with inline functions. The compiler is completely free to
choose which concrete calls to inline and which not to inline.

It is obvious that in general case indirect calls cannot be inlined.
This, however, doesn't in any way prevent direct calls from being inlined.
Wouldn't that pretty much defeat
the purpose, by forcing the compiler to generate code for the function at
a specific location?
No. Why? Direct calls that have access to the inline definition of the
function can still be perfectly inlined. No problems here. Other calls
(indirect calls or calls that have no access to the inline definition)
are made in the "traditional" way. It is up to you to design and
organize your program the way that maximizes inlining (if that's what
you wish to achieve).
My point of reference isn't C++, but the C `register' keyword. It turns
out that C compilers are under no obligation to listen to the programmer
about which variables to try and place in registers (and on plenty of
machines, there are so few registers that tying one up is stupid), but the
compiler is obligated to act as if it had by disallowing the taking of the
address of a register-qualified variable.


It is a bad analogy. The fundamental difference between function and
variables that makes this a bad analogy is that functions are "frozen",
they don't change. If some entity is "frozen", there's no problem in
keeping and using several copies of that entity - no one would ever
notice and no one would ever know which copy is being used in each
particular case.

With functions the property of being 'inline' is a property of the
function itself, while the property of being actually _inlined_ is a
property of a concrete function call. Different calls to the same
function can have different properties (i.e. they can be inlined or they
can be directed to a "regular" function body), they don't conflict with
each other. It is a very natural separation, it requires relatively
little effort from the compiler and imposes no performance penalties.

Variables, on the other hand, can change their values. In order to keep
several copies of a variable (a 'register' copy and a normal copy in
memory, to allow address taking) the program will have to make sure that
values stored in these copies are carefully synchronized. This is very
difficult, if at all possible (frankly, I don't think it is). And in any
case this will impose significant run-time performance penalty.

Now, with _const-qualified objects declared with 'register' keyword
address-taking would be easy to implement, just because constants are
similar to functions - they don't change.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #12
Chris Barts wrote:
>> ...
>> Placing the inline keyword on all static (module-local) functions is an>> okay thing to do, if you trust your compiler; it'll figure out when not>> to do it, although you can't take an inline function's address to call>> it indirectly, and you'll look a bit silly.


While it is true that an indirect call cannot be inlined (for obvious
reasons), there is absolutely no problem with taking an address of an
inline function. You seem to be mistaking two different things: inline
functions and inlined calls to functions.

This seems odd to me, too: If the function `should' be inlined (and,
therefore, have no independent existence), what is the rationale for
allowing programmers to take its address?

Declaring a function as 'inline' never meant that is has no "independent
existence".

The decision to inline a call is made by the compiler on a per-call
basis. Nothing in the language specification says that a function should
be either always inlined or never inlined. This has never been the
intention with inline functions. The compiler is completely free to
choose which concrete calls to inline and which not to inline.

It is obvious that in general case indirect calls cannot be inlined.
This, however, doesn't in any way prevent direct calls from being inlined.

Wouldn't that pretty much defeat
the purpose, by forcing the compiler to generate code for the function at
a specific location?

No. Why? Direct calls that have access to the inline definition of the
function can still be perfectly inlined. No problems here. Other calls
(indirect calls or calls that have no access to the inline definition)
are made in the "traditional" way. It is up to you to design and
organize your program the way that maximizes inlining (if that's what
you wish to achieve).

My point of reference isn't C++, but the C `register' keyword. It turns
out that C compilers are under no obligation to listen to the programmer
about which variables to try and place in registers (and on plenty of
machines, there are so few registers that tying one up is stupid), but the compiler is obligated to act as if it had by disallowing the taking of the address of a register-qualified variable.

It is a bad analogy. The fundamental difference between function and
variables that makes this a bad analogy is that functions are "frozen",
they don't change. If some entity is "frozen", there's no problem in
keeping and using several copies of that entity - no one would ever
notice and no one would ever know which copy is being used in each
particular case.

With functions the property of being 'inline' is a property of the
function itself, while the property of being actually _inlined_ is a
property of a concrete function call. Different calls to the same
function can have different properties (i.e. they can be inlined or they
can be directed to a "regular" function body), they don't conflict with
each other. It is a very natural separation, it requires relatively
little effort from the compiler and imposes no performance penalties.

Variables, on the other hand, can change their values. In order to keep
several copies of a variable (a 'register' copy and a normal copy in
memory, to allow address taking) the program will have to make sure that
values stored in these copies are carefully synchronized. This is very
difficult, if at all possible (frankly, I don't think it is). And in any
case this will impose significant run-time performance penalty.

Now, with _const-qualified objects declared with 'register' keyword
address-taking would be easy to implement, just because constants are
similar to functions - they don't change.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #13
CBFalconer wrote:
E. Robert Tisdale wrote:
Method Man wrote:
If I don't care about the size of my executable or compile time,
is there any reason why I wouldn't want to inline every function
in my code to make the program run more efficient?
No.
You may find that you want to define than as "inline static"
in a header file so that you don't get "multiply defined references".


If the function is static,
there is no point in mentioning it in any header file.
Headers should be used solely to export things from a compilation unit.
Static functions are not accessible outside the compilation unit.

cat file.h #ifndef GUARD_FILE_H
#define GUARD_FILE_H 1

inline
double f(double x) {
return x*(x + 2.0) + 1.0;
}

double g(double x);

#endif//GUARD_FILE_H
cat file.c #include "file.h"

double g(double x) {
return f(x);
}
cat main.c #include <stdio.h>
#include "file.h"

int main(int argc, char* argv[]) {
fprintf(stdout, "f(13.0) = %f\n", f(13.0));
fprintf(stdout, "g(13.0) = %f\n", g(13.0));
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c file.c

/tmp/ccCBkYgj.o(.text+0x0): In function `f':
: multiple definition of `f'
/tmp/ccqaborv.o(.text+0x0): first defined here
collect2: ld returned 1 exit status

The definition of f(double)
must appear in both translation units if it is to be inlined
but the link editor will see multiple definitions
unless it is also static.
Nov 14 '05 #14
E. Robert Tisdale wrote:
....
> gcc -Wall -std=c99 -pedantic -o main main.c file.c

/tmp/ccCBkYgj.o(.text+0x0): In function `f':
: multiple definition of `f'
/tmp/ccqaborv.o(.text+0x0): first defined here
collect2: ld returned 1 exit status

The definition of f(double)
must appear in both translation units if it is to be inlined
but the link editor will see multiple definitions
unless it is also static.


http://gcc.gnu.org/onlinedocs/gcc/Inline.html
http://gcc.gnu.org/c99status.html
Nov 14 '05 #15
"E. Robert Tisdale" wrote:
CBFalconer wrote:
E. Robert Tisdale wrote:
Method Man wrote:

If I don't care about the size of my executable or compile time,
is there any reason why I wouldn't want to inline every function
in my code to make the program run more efficient?

No.
You may find that you want to define than as "inline static"
in a header file so that you don't get "multiply defined references".
If the function is static,
there is no point in mentioning it in any header file.
Headers should be used solely to export things from a compilation unit.
Static functions are not accessible outside the compilation unit.


#ifndef GUARD_FILE_H
#define GUARD_FILE_H 1

inline
double f(double x) {
return x*(x + 2.0) + 1.0;
}
double g(double x);
#endif//GUARD_FILE_H

.... snip ...
The definition of f(double) must appear in both translation
units if it is to be inlined but the link editor will see
multiple definitions unless it is also static.


You have a point. However I consider any code so organized an
abortion.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #16
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
"E. Robert Tisdale" wrote:
CBFalconer wrote:
E. Robert Tisdale wrote:
Method Man wrote:

> If I don't care about the size of my executable or compile time,
> is there any reason why I wouldn't want to inline every function
> in my code to make the program run more efficient?


The definition of f(double) must appear in both translation
units if it is to be inlined but the link editor will see
multiple definitions unless it is also static.


You have a point. However I consider any code so organized an
abortion.


And how does that affect performance, exactly?

--
Mabden
Nov 14 '05 #17
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
"E. Robert Tisdale" wrote:
CBFalconer wrote:
If the function is static,
there is no point in mentioning it in any header file.
Headers should be used solely to export things from a compilation unit.
Static functions are not accessible outside the compilation unit.
.... The definition of f(double) must appear in both translation
units if it is to be inlined but the link editor will see
multiple definitions unless it is also static.


You have a point. However I consider any code so organized an
abortion.


Why?

I'd considered inline static functions in a header file to be a reasonable
replacement for many macros, such as replacing

#define ADD(x,y) ((x)+(y))

with

inline static int add(int x, int y) { return x+y; }

Obviously the latter version isn't type-flexible, but that may be an
advantage in many cases.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

Nov 14 '05 #18
Stephen Sprunk wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
"E. Robert Tisdale" wrote:
CBFalconer wrote: If the function is static,
there is no point in mentioning it in any header file. Headers
should be used solely to export things from a compilation unit.
Static functions are not accessible outside the compilation unit. ... The definition of f(double) must appear in both translation
units if it is to be inlined but the link editor will see
multiple definitions unless it is also static.


You have a point. However I consider any code so organized an
abortion.


Why?

I'd considered inline static functions in a header file to be a
reasonable replacement for many macros, such as replacing

#define ADD(x,y) ((x)+(y))

with

inline static int add(int x, int y) { return x+y; }

Obviously the latter version isn't type-flexible, but that may
be an advantage in many cases.


You too have a point. Yet I would still consider it unclean, and
would prefer to put that definition directly in the file in
question. Similarly, I would not like to see such a #define in a
header file. My principle remains that header files are intended
to export connections to a compilation unit. That way I remain
free to alter that unit without having to worry about effects on
(possibly myriad) other units, as long as I do not modify the
header(s).

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #19

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

Similar topics

5
by: Tony Johansson | last post by:
Hello experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that sound strange. Here is the whole section: It says" Because...
0
by: dotnet | last post by:
I am trying to make a page that is changing the page schema(colors and graphics) depends on the specific value (for example, test.aspx?page=1) I have so far achieved accepting page values (with...
2
by: Showjumper | last post by:
Is there a peformance hit when using inline code? As an example, lets i store a user's preferences for backgtound color of a page. When he/she logs in, i stick the color value into their session...
1
by: itaitai2003 | last post by:
I'm attempting to configure the DISPLAY attribute using inline code but without success. (I don't want to use the Panel) Any ideas? <div id="panel" style="DISPLAY: <%# GetDisplayStatus() %> ">...
6
by: Anders M | last post by:
I'm trying to use Inline-code to call Page_load, Page_Init or Page_PreRender methods. I've also got a code behind c#-file. I can define inline methods for buttons and so on...that works fine....
4
by: Wendy Elizabeth | last post by:
I have the following questions about VB.NET interfacing with sql server 2000: 1. I have heard that VB.NET can run with inline SQL. Can you show me how to use inline sql to access a sql server 2000...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.