Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #28602 > unrolled thread

inline functions

Started by"BartC" <bc@freeuk.com>
First post2012-11-24 12:20 +0000
Last post2012-11-25 01:18 -0800
Articles 20 on this page of 58 — 20 participants

Back to article view | Back to comp.lang.c


Contents

  inline functions "BartC" <bc@freeuk.com> - 2012-11-24 12:20 +0000
    Re: inline functions SG <sgesemann@gmail.invalid> - 2012-11-24 14:52 +0100
      Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-24 14:48 +0000
        Re: inline functions Joost Kraaijeveld <J.Kraaijeveld@Askesis.nl> - 2012-11-24 15:59 +0100
        Re: inline functions Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2012-11-24 16:25 +0100
        Re: inline functions Johann Klammer <klammerj@NOSPAM.a1.net> - 2012-11-24 19:18 +0100
    Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-11-24 15:07 +0000
      Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-24 15:33 +0000
        Re: inline functions Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2012-11-24 17:17 +0100
          Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-24 16:39 +0000
            Re: inline functions Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2012-11-24 18:13 +0100
              Re: inline functions Jens Gustedt <jens.gustedt@loria.fr> - 2012-11-24 19:36 +0100
                Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-12-05 03:19 -0200
                  Re: inline functions Jens Gustedt <jens.gustedt@loria.fr> - 2012-12-05 10:57 +0100
                    Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-12-05 15:34 -0200
          Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-11-25 09:43 +0000
            Re: inline functions Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2012-11-25 11:32 +0100
              Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-11-27 21:55 +0000
          Re: inline functions "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-11-26 04:16 -0800
            Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-26 14:13 +0100
              Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-11-28 21:27 +0000
                Re: inline functions James Kuyper <jameskuyper@verizon.net> - 2012-11-28 16:40 -0500
                  Re: inline functions Ben Pfaff <blp@cs.stanford.edu> - 2012-11-28 14:15 -0800
                    Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-11-29 00:02 -0200
                  Re: inline functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-11-29 07:24 -0800
                    Re: inline functions James Kuyper <jameskuyper@verizon.net> - 2012-11-29 11:04 -0500
                      Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-11-29 14:44 -0200
                        Re: inline functions Les Cargill <lcargill99@comcast.com> - 2012-11-29 12:44 -0600
                          Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-11-29 20:43 -0200
                            Re: inline functions Les Cargill <lcargill99@comcast.com> - 2012-11-29 20:14 -0600
                      Re: inline functions Ian Collins <ian-news@hotmail.com> - 2012-11-30 07:44 +1300
                        Re: inline functions Sergio Durigan Junior <sergiodj@riseup.net> - 2012-11-29 20:38 -0200
                  Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-12-05 03:17 +0000
                    Re: inline functions Noob <root@127.0.0.1> - 2012-12-05 11:26 +0100
        Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-26 11:23 +0100
          Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-26 13:01 +0000
            Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-26 14:24 +0100
              Re: inline functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-11-26 05:35 -0800
                Re: inline functions Les Cargill <lcargill99@comcast.com> - 2012-11-26 07:57 -0600
                  Re: inline functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-11-26 07:07 -0800
                Re: inline functions Rosario1903 <Rosario@invalid.invalid> - 2012-11-27 09:46 +0100
                Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-27 10:50 +0100
              Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-26 14:14 +0000
                Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-26 15:14 +0000
                Re: inline functions Rosario1903 <Rosario@invalid.invalid> - 2012-11-27 09:46 +0100
                  Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-27 14:41 +0000
                Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-27 11:01 +0100
                  Re: inline functions "BartC" <bc@freeuk.com> - 2012-11-27 14:37 +0000
                    Re: inline functions Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2012-11-27 18:22 +0100
                    Re: inline functions James Kuyper <jameskuyper@verizon.net> - 2012-11-27 12:55 -0500
                  Re: inline functions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-11-27 22:06 +0000
                    Re: inline functions David Brown <david@westcontrol.removethisbit.com> - 2012-11-29 09:47 +0100
            Re: inline functions glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-11-26 14:39 +0000
    Re: inline functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-11-24 07:20 -0800
      Re: inline functions James Kuyper <jameskuyper@verizon.net> - 2012-11-24 10:44 -0500
    Re: inline functions James Kuyper <jameskuyper@verizon.net> - 2012-11-24 10:35 -0500
    Re: inline functions Philip Lantz <prl@canterey.us> - 2012-11-24 22:56 -0800
    Re: inline functions James Dow Allen <jdallen2000@yahoo.com> - 2012-11-25 01:18 -0800

Page 1 of 3  [1] 2 3  Next page →


#28602 — inline functions

From"BartC" <bc@freeuk.com>
Date2012-11-24 12:20 +0000
Subjectinline functions
Message-ID<ZY2ss.472895$9D6.428279@fx27.am4>
Is there a way of controlling which functions are inlined, or likely to be 
inlined, and which ones you never want inlined? Especially with gcc...

(I have a file with over 300 functions, each of which is called at most 
once. Strange things are happening with performance, such as being 60% 
slower, when, for example, a function's body is populated with code (they 
start off empty), even though the function is never actually called.

I assume this is due to selective inlining. At the moment I've had to 
segregate the functions from the calls, to avoid undue influence on 
performance, but want to benefit from inlining later on, without having to 
re-integrate the functions one by one.)

-- 
Bartc  

[toc] | [next] | [standalone]


#28603

FromSG <sgesemann@gmail.invalid>
Date2012-11-24 14:52 +0100
Message-ID<k8qje7$je1$2@news.albasani.net>
In reply to#28602
Am 24.11.2012 13:20, schrieb BartC:
> Is there a way of controlling which functions are inlined, or likely to
> be inlined, and which ones you never want inlined? Especially with gcc...

Yes, I think there is. RTFM.

Cheers!
SG

[toc] | [prev] | [next] | [standalone]


#28605

From"BartC" <bc@freeuk.com>
Date2012-11-24 14:48 +0000
Message-ID<H75ss.335838$Wc4.85412@fx10.am4>
In reply to#28603

"SG" <sgesemann@gmail.invalid> wrote in message 
news:k8qje7$je1$2@news.albasani.net...
> Am 24.11.2012 13:20, schrieb BartC:
>> Is there a way of controlling which functions are inlined, or likely to
>> be inlined, and which ones you never want inlined? Especially with gcc...
>
> Yes, I think there is. RTFM.

OK. My experience of trying to extract useful information out of gcc docs is 
that it's not very rewarding...

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#28607

FromJoost Kraaijeveld <J.Kraaijeveld@Askesis.nl>
Date2012-11-24 15:59 +0100
Message-ID<50B0E0BA.6060802@Askesis.nl>
In reply to#28605
On 24/11/12 15:48, BartC wrote:
>
>
> "SG" <sgesemann@gmail.invalid> wrote in message
> news:k8qje7$je1$2@news.albasani.net...
>> Am 24.11.2012 13:20, schrieb BartC:
>>> Is there a way of controlling which functions are inlined, or likely to
>>> be inlined, and which ones you never want inlined? Especially with
>>> gcc...
>>
>> Yes, I think there is. RTFM.
>
> OK. My experience of trying to extract useful information out of gcc
> docs is that it's not very rewarding...
>
Because a just "RTFM" is not really helpful to begin with, and rude in 
the worst case:

google "force inlining gcc", first entry:

http://stackoverflow.com/questions/8381293/how-do-i-force-gcc-to-inline-a-function

[toc] | [prev] | [next] | [standalone]


#28612

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2012-11-24 16:25 +0100
Message-ID<87d2z36n0i.fsf@dpt-info.u-strasbg.fr>
In reply to#28605
"BartC" <bc@freeuk.com> writes:

> "SG" <sgesemann@gmail.invalid> wrote in message
> news:k8qje7$je1$2@news.albasani.net...
>> Am 24.11.2012 13:20, schrieb BartC:
>>> Is there a way of controlling which functions are inlined, or likely to
>>> be inlined, and which ones you never want inlined? Especially with gcc...
>>
>> Yes, I think there is. RTFM.
>
> OK. My experience of trying to extract useful information out of gcc
> docs is that it's not very rewarding...

Function attributes are described here:

http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#Function-Attributes

Command line options are here:

http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options.html#Optimize-Options

Search for "inline". Be careful if you need portable code.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#28624

FromJohann Klammer <klammerj@NOSPAM.a1.net>
Date2012-11-24 19:18 +0100
Message-ID<50b10f88$0$1565$91cee783@newsreader04.highway.telekom.at>
In reply to#28605
BartC wrote:
>
>
> "SG" <sgesemann@gmail.invalid> wrote in message
> news:k8qje7$je1$2@news.albasani.net...
>> Am 24.11.2012 13:20, schrieb BartC:
>>> Is there a way of controlling which functions are inlined, or likely to
>>> be inlined, and which ones you never want inlined? Especially with
>>> gcc...
>>
>> Yes, I think there is. RTFM.
>
> OK. My experience of trying to extract useful information out of gcc
> docs is that it's not very rewarding...
>

The problem is that most people try the manpage first, which is an ugly 
unstructured lump of information. Try the info manual or the html 
version instead. It is much better structured.

[toc] | [prev] | [next] | [standalone]


#28608

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2012-11-24 15:07 +0000
Message-ID<slrnkb1okj.1jc.grahn+nntp@frailea.sa.invalid>
In reply to#28602
On Sat, 2012-11-24, BartC wrote:
> Is there a way of controlling which functions are inlined, or likely to be 
> inlined, and which ones you never want inlined? Especially with gcc...
>
> (I have a file with over 300 functions, each of which is called at most 
> once. Strange things are happening with performance, such as being 60% 
> slower, when, for example, a function's body is populated with code (they 
> start off empty), even though the function is never actually called.

Care to provide a complete example?  This seems highly unlikely -- a
function which is never called will simply be discarded by the compiler.
Worst case it will be sitting there doing nothing, perhaps making the
CPU's instruction cache work a little bit less well.

> I assume this is due to selective inlining. At the moment I've had to 
> segregate the functions from the calls, to avoid undue influence on 
> performance, but want to benefit from inlining later on, without having to 
> re-integrate the functions one by one.)

I don't understand this. How can this be because of inlining, and yet
you don't have inlining?

More generally, my own rules of thumb:
- things I'm quite sure will be useful to inline, and which
  are called in several translation units:
  -> 'static inline' in some header file
- anything else:
  -> 'static', and trust the compiler to choose wisely
- play with the optimization level (-O2, -O3, -Os in gcc)
- look at the object code if I want to know the outcome

- in the unlikely case that I need more performance /and/ believe
  this is a worthwhile area to investigate, I'd read the GCC manual.
  I know it covers this.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#28613

From"BartC" <bc@freeuk.com>
Date2012-11-24 15:33 +0000
Message-ID<ON5ss.547483$9H4.97721@fx17.am4>
In reply to#28608

"Jorgen Grahn" <grahn+nntp@snipabacken.se> wrote in message
news:slrnkb1okj.1jc.grahn+nntp@frailea.sa.invalid...
> On Sat, 2012-11-24, BartC wrote:
>> Is there a way of controlling which functions are inlined, or likely to
>> be
>> inlined, and which ones you never want inlined? Especially with gcc...
>>
>> (I have a file with over 300 functions, each of which is called at most
>> once. Strange things are happening with performance, such as being 60%
>> slower, when, for example, a function's body is populated with code (they
>> start off empty), even though the function is never actually called.
>
> Care to provide a complete example?  This seems highly unlikely -- a
> function which is never called will simply be discarded by the compiler.

The module is an interpreter dispatch loop. I'm experimenting with several;
this one has one function containing a switch statement with 300 cases. Each
case calls a corresponding function in the rest of the module.

So a call to each function exists in the source, but is never called in
practice (at least, not in the specific bytecode program being executed that
exhibited the slowdown).

The compiler has no way of knowing which of the 300 cases will be called (it
depends on what bytecode is being executed), nor how often. I, on the other
hand, have a much better idea! So I don't need rarely executed handlers
inlined for example.

There are various ways to tackle this, but it would be most convenient if
there was an attribute 'never_inline' (I think there is one to always
inline).

>> I assume this is due to selective inlining. At the moment I've had to
>> segregate the functions from the calls, to avoid undue influence on
>> performance, but want to benefit from inlining later on, without having
>> to
>> re-integrate the functions one by one.)
>
> I don't understand this. How can this be because of inlining, and yet
> you don't have inlining?

Inlining must be happening at a result of optimisation. I haven't yet
explicitly told it not to (except by moving all the functions to another
file).

> More generally, my own rules of thumb:
> - things I'm quite sure will be useful to inline, and which
>  are called in several translation units:
>  -> 'static inline' in some header file

I use 'static' on all of the functions (because they are not exported).
Perhaps I should look at that...

> - look at the object code if I want to know the outcome

(That's another thing: I've tried several incantations to get gcc to produce
assembler in a .s file, that contains some cross-references to the original 
C
source. Haven't managed it yet..)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#28617

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2012-11-24 17:17 +0100
Message-ID<87624v6kly.fsf@dpt-info.u-strasbg.fr>
In reply to#28613
"BartC" <bc@freeuk.com> writes:

> "Jorgen Grahn" <grahn+nntp@snipabacken.se> wrote in message
> news:slrnkb1okj.1jc.grahn+nntp@frailea.sa.invalid...
>> On Sat, 2012-11-24, BartC wrote:
>>> Is there a way of controlling which functions are inlined, or likely to
>>> be
>>> inlined, and which ones you never want inlined? Especially with gcc...
>>>
>>> (I have a file with over 300 functions, each of which is called at most
>>> once. Strange things are happening with performance, such as being 60%
>>> slower, when, for example, a function's body is populated with code (they
>>> start off empty), even though the function is never actually called.
>>
>> Care to provide a complete example?  This seems highly unlikely -- a
>> function which is never called will simply be discarded by the compiler.
>
> The module is an interpreter dispatch loop. I'm experimenting with several;
> this one has one function containing a switch statement with 300 cases. Each
> case calls a corresponding function in the rest of the module.
>
> So a call to each function exists in the source, but is never called in
> practice (at least, not in the specific bytecode program being executed that
> exhibited the slowdown).
>
> The compiler has no way of knowing which of the 300 cases will be called (it
> depends on what bytecode is being executed), nor how often. I, on the other
> hand, have a much better idea! So I don't need rarely executed handlers
> inlined for example.
>
> There are various ways to tackle this, but it would be most convenient if
> there was an attribute 'never_inline' (I think there is one to always
> inline).

It goes the other way round: there is a command line option
(-fno-inline-functions) to prevent inlining, and an attribute
always_inline to force inlining (of inline functions).

>>> I assume this is due to selective inlining. At the moment I've had to
>>> segregate the functions from the calls, to avoid undue influence on
>>> performance, but want to benefit from inlining later on, without having
>>> to
>>> re-integrate the functions one by one.)
>>
>> I don't understand this. How can this be because of inlining, and yet
>> you don't have inlining?
>
> Inlining must be happening at a result of optimisation. I haven't yet
> explicitly told it not to (except by moving all the functions to another
> file).

If inlining is enabled, the compiler will decide whether or not to
inline on a per-callsite basis, not on a per-function (callee) basis. It
doesn't make much difference in your case iiuc. But keep in mind that
the call site is important. With a 300-case switch, it is likely that
the compiler will find your function too big and will refrain from
making it bigger.

>> More generally, my own rules of thumb:
>> - things I'm quite sure will be useful to inline, and which
>>  are called in several translation units:
>>  -> 'static inline' in some header file
>
> I use 'static' on all of the functions (because they are not exported).
> Perhaps I should look at that...

static will make the compiler not emit code when all calls have been
inlined. It should not influence the inlining decision.

>> - look at the object code if I want to know the outcome
>
> (That's another thing: I've tried several incantations to get gcc to
> produce assembler in a .s file, that contains some cross-references to
> the original C source. Haven't managed it yet..)

objdump -d -l will print file:line on an image containing debug info.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#28620

From"BartC" <bc@freeuk.com>
Date2012-11-24 16:39 +0000
Message-ID<zN6ss.970994$it2.113406@fx22.am4>
In reply to#28617
"Alain Ketterlin" <alain@dpt-info.u-strasbg.fr> wrote in message
news:87624v6kly.fsf@dpt-info.u-strasbg.fr...
> "BartC" <bc@freeuk.com> writes:

>> There are various ways to tackle this, but it would be most convenient if
>> there was an attribute 'never_inline' (I think there is one to always
>> inline).
>
> It goes the other way round: there is a command line option
> (-fno-inline-functions) to prevent inlining, and an attribute
> always_inline to force inlining (of inline functions).

I want to disable inlining of some functions (which I don't want inlined at
the expense of more useful ones), but still benefit from it with other
functions that I consider are called more frequently.

If 'always_inline' overrides -fno-inline-functions, that will do the trick.
But then your other link said there was a specific 'noinline' attribute, 
which will be perfect if it works. Thanks!

>> Inlining must be happening at a result of optimisation. I haven't yet
>> explicitly told it not to (except by moving all the functions to another
>> file).
>
> If inlining is enabled, the compiler will decide whether or not to
> inline on a per-callsite basis, not on a per-function (callee) basis. It
> doesn't make much difference in your case iiuc. But keep in mind that
> the call site is important. With a 300-case switch, it is likely that
> the compiler will find your function too big and will refrain from
> making it bigger.

Hence the need to control which ones *are* inlined. But I don't know why it
cares how big my function is, if I'm optimising for speed. Doubtless there
will be option for that somewhere too.

(Of course I can always just write the code inline anyway, but it's
difficult to manage and gets unwieldy at a source code level.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#28622

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2012-11-24 18:13 +0100
Message-ID<871ufi7wl3.fsf@dpt-info.u-strasbg.fr>
In reply to#28620
"BartC" <bc@freeuk.com> writes:

>>> There are various ways to tackle this, but it would be most convenient if
>>> there was an attribute 'never_inline' (I think there is one to always
>>> inline).
>>
>> It goes the other way round: there is a command line option
>> (-fno-inline-functions) to prevent inlining, and an attribute
>> always_inline to force inlining (of inline functions).
>
> I want to disable inlining of some functions (which I don't want inlined at
> the expense of more useful ones), but still benefit from it with other
> functions that I consider are called more frequently.
>
> If 'always_inline' overrides -fno-inline-functions, that will do the trick.
> But then your other link said there was a specific 'noinline'
> attribute, which will be perfect if it works. Thanks!

Hmm, yes, gcc's options/attributes are many...

Check also the various debugging options, especially -dump-ipa-inline
(the objdump -l trick may be easier, though, if all you want is to check
whether calls are still there).

[...]
> Hence the need to control which ones *are* inlined. But I don't know why it
> cares how big my function is, if I'm optimising for speed.

It's really hard to control code size, i.e., avoid explosion. I guess
the compiler has to be somewhat conservative.

> Doubtless there will be option for that somewhere too.

Gcc has parameters (that you can set with --param if you want) to set
various limits, e.g., large-function-growth and large-function-insns.

> (Of course I can always just write the code inline anyway, but it's
> difficult to manage and gets unwieldy at a source code level.)

Sure.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#28625

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-11-24 19:36 +0100
Message-ID<50B1139C.1080501@loria.fr>
In reply to#28622
Am 24.11.2012 18:13, schrieb Alain Ketterlin:
> "BartC" <bc@freeuk.com> writes:
> 
>>>> There are various ways to tackle this, but it would be most convenient if
>>>> there was an attribute 'never_inline' (I think there is one to always
>>>> inline).
>>>
>>> It goes the other way round: there is a command line option
>>> (-fno-inline-functions) to prevent inlining, and an attribute
>>> always_inline to force inlining (of inline functions).
>>
>> I want to disable inlining of some functions (which I don't want inlined at
>> the expense of more useful ones), but still benefit from it with other
>> functions that I consider are called more frequently.
>>
>> If 'always_inline' overrides -fno-inline-functions, that will do the trick.
>> But then your other link said there was a specific 'noinline'
>> attribute, which will be perfect if it works. Thanks!
> 
> Hmm, yes, gcc's options/attributes are many...
> 
> Check also the various debugging options, especially -dump-ipa-inline
> (the objdump -l trick may be easier, though, if all you want is to check
> whether calls are still there).

or change to clang, that produces quite readable, annotated assembler
with the -S option, for which it is much easier to keep track of the
source lines, much better than gcc

Jens

[toc] | [prev] | [next] | [standalone]


#28940

FromSergio Durigan Junior <sergiodj@riseup.net>
Date2012-12-05 03:19 -0200
Message-ID<87hao1m5y2.fsf@riseup.net>
In reply to#28625
On Saturday, November 24 2012, Jens Gustedt wrote:

> or change to clang, that produces quite readable, annotated assembler
> with the -S option, for which it is much easier to keep track of the
> source lines, much better than gcc

Don't want to cause any flamewars here (nor to hijack the thread), but
can you provide an example?  You can use the various -d* (I'm thinking
about -dp here, actually) options on GCC to make it annotate the
assembler.  Don't know how clang annotates it, I don't have it installed
here.

Thanks,

-- 
Sergio

[toc] | [prev] | [next] | [standalone]


#28942

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-12-05 10:57 +0100
Message-ID<50BF1A99.7060708@loria.fr>
In reply to#28940
Am 05.12.2012 06:19, schrieb Sergio Durigan Junior:
> On Saturday, November 24 2012, Jens Gustedt wrote:
> 
>> or change to clang, that produces quite readable, annotated assembler
>> with the -S option, for which it is much easier to keep track of the
>> source lines, much better than gcc
> 
> Don't want to cause any flamewars here (nor to hijack the thread),

me neither

> but can you provide an example?

> You can use the various -d* (I'm thinking
> about -dp here, actually) options on GCC to make it annotate the
> assembler.

-dp provides a very low level annotation of every assembler statement,
usually not what *I* need to understand the assembler something like

uComp:
.LFB683:
	.cfi_startproc
	testq	%rdx, %rdx	# 10	*cmpdi_ccno_1/1	[length = 3]
	je	.L586	# 11	*jcc_1	[length = 2]
	movq	(%rdx), %rcx	# 13	*movdi_internal_rex64/2	[length = 3]
	xorl	%edx, %edx	# 88	*movdi_xor	[length = 2]
	movq	(%rdi), %rax	# 14	*movdi_internal_rex64/2	[length = 3]
	divq	%rcx	# 76	*udivmoddi4_noext	[length = 3]
	movq	(%rsi), %rax	# 17	*movdi_internal_rex64/2	[length = 3]
	movq	%rdx, %rdi	# 71	*movdi_internal_rex64/2	[length = 3]
	xorl	%edx, %edx	# 89	*movdi_xor	[length = 2]
	divq	%rcx	# 78	*udivmoddi4_noext	[length = 3]
	xorl	%ecx, %ecx	# 90	*movsi_xor	[length = 2]
	cmpq	%rdx, %rdi	# 91	*cmpdi_1/1	[length = 3]
	movl	$-1, %eax	# 7	*movsi_internal/1	[length = 5]
	seta	%cl	# 92	*setcc_qi_slp	[length = 3]
	cmovae	%ecx, %eax	# 63	*movsicc_noc/1	[length = 3]
	ret	# 82	return_internal	[length = 1]
	.p2align 4,,10
	.p2align 3
.L586:
	movq	(%rsi), %rcx	# 72	*movdi_internal_rex64/2	[length = 3]
	xorl	%edx, %edx	# 85	*movsi_xor	[length = 2]
	movl	$-1, %eax	# 6	*movsi_internal/1	[length = 5]
	cmpq	%rcx, (%rdi)	# 86	*cmpdi_1/1	[length = 3]
	seta	%dl	# 87	*setcc_qi_slp	[length = 3]
	cmovae	%edx, %eax	# 67	*movsicc_noc/1	[length = 3]
	ret	# 84	return_internal	[length = 1]
	.cfi_endproc
.LFE683:
	.size	uComp, .-uComp


> Don't know how clang annotates it, I don't have it installed
> here.

Clang (with just -S) annotates the same code more lightly but with
higher level annotations corresponding to the structure of the source,
here in particular the if-then-else constructs that generated the
branching.

uComp:                                  # @uComp
	.cfi_startproc
# BB#0:                                 # %entry
	testq	%rdx, %rdx
	je	.LBB9_3
# BB#1:                                 # %if.then
	movq	(%rsi), %rax
	movq	(%rdx), %rsi
	xorl	%edx, %edx
	divq	%rsi
	movq	%rdx, %rcx
	movq	(%rdi), %rax
	xorl	%edx, %edx
	divq	%rsi
	movl	$-1, %eax
	cmpq	%rcx, %rdx
	jb	.LBB9_5
# BB#2:                                 # %cond.false
	cmpq	%rcx, %rdx
	jmp	.LBB9_4
.LBB9_3:                                # %if.else
	movq	(%rsi), %rcx
	movq	(%rdi), %rdx
	movl	$-1, %eax
	cmpq	%rcx, %rdx
	jb	.LBB9_5
.LBB9_4:                                # %cond.false.i
	seta	%al
	movzbl	%al, %eax
.LBB9_5:                                # %return
	ret
.Ltmp115:
	.size	uComp, .Ltmp115-uComp
	.cfi_endproc


Jens

[toc] | [prev] | [next] | [standalone]


#28949

FromSergio Durigan Junior <sergiodj@riseup.net>
Date2012-12-05 15:34 -0200
Message-ID<87boe8mmgy.fsf@riseup.net>
In reply to#28942
On Wednesday, December 05 2012, Jens Gustedt wrote:

>> but can you provide an example?
>
>> You can use the various -d* (I'm thinking
>> about -dp here, actually) options on GCC to make it annotate the
>> assembler.
>
> -dp provides a very low level annotation of every assembler statement,
> usually not what *I* need to understand the assembler something like

Yeah, it is very low level indeed.

>> Don't know how clang annotates it, I don't have it installed
>> here.
>
> Clang (with just -S) annotates the same code more lightly but with
> higher level annotations corresponding to the structure of the source,
> here in particular the if-then-else constructs that generated the
> branching.

Ok, I see it.

You can achieve the same effect with GCC by compiling the program with
-g (debug information) and using `objdump -S' on the binary.  It will
give you an output like:

    00000000004004a9 <main>:

    int
    main ()
    {
      4004a9:       55                      push   %rbp
      4004aa:       48 89 e5                mov    %rsp,%rbp
      4004ad:       48 83 ec 10             sub    $0x10,%rsp
      int a;

      a = 10;
      4004b1:       c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)

      if (a < 20)
      4004b8:       83 7d fc 13             cmpl   $0x13,-0x4(%rbp)
      4004bc:       7f 0c                   jg     4004ca <main+0x21>
        foo ();
      4004be:       e8 d9 ff ff ff          callq  40049c <foo>
      else
        return 0;

      return 0;
      4004c3:       b8 00 00 00 00          mov    $0x0,%eax
      4004c8:       eb 05                   jmp    4004cf <main+0x26>
      a = 10;

      if (a < 20)
        foo ();
      else
        return 0;
      4004ca:       b8 00 00 00 00          mov    $0x0,%eax

      return 0;
    }
      4004cf:       c9                      leaveq 
      4004d0:       c3                      retq   
      4004d1:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
      4004d8:       00 00 00 
      4004db:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

Anyway, different ways to do it with different tools.

Regards,

-- 
Sergio

[toc] | [prev] | [next] | [standalone]


#28637

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2012-11-25 09:43 +0000
Message-ID<slrnkb3q1u.1jc.grahn+nntp@frailea.sa.invalid>
In reply to#28617
On Sat, 2012-11-24, Alain Ketterlin wrote:
> "BartC" <bc@freeuk.com> writes:
>
>> "Jorgen Grahn" <grahn+nntp@snipabacken.se> wrote in message
>> news:slrnkb1okj.1jc.grahn+nntp@frailea.sa.invalid...
...
>>> More generally, my own rules of thumb:
>>> - things I'm quite sure will be useful to inline, and which
>>>  are called in several translation units:
>>>  -> 'static inline' in some header file

I think BartC is responding to this by me, which he snipped:

>>> - anything else:
>>>   -> 'static', and trust the compiler to choose wisely

>> I use 'static' on all of the functions (because they are not exported).
>> Perhaps I should look at that...
>
> static will make the compiler not emit code when all calls have been
> inlined. It should not influence the inlining decision.

Why not?  Just the emit/not emit choice should influence the inlining
decision, because this in turn influences code size.

Let's say I have this in a translation unit:

   int foo(void) { /* pages of code */ }
   int bar(void) {
      int n = foo();
      /* other stuff */
   }

I'd expect a compiler to have a conservative inlining mode which
doesn't inline foo() in this case, to avoid code bloat.
(Especially since you're almost certain to have foo() calls in other
translation units, or you would have made it static.)

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#28638

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2012-11-25 11:32 +0100
Message-ID<87sj7y55xj.fsf@dpt-info.u-strasbg.fr>
In reply to#28637
Jorgen Grahn <grahn+nntp@snipabacken.se> writes:

[...]
>> static will make the compiler not emit code when all calls have been
>> inlined. It should not influence the inlining decision.
>
> Why not?

You're right, my phrasing was misleading. What I meant was: static will
not *by itself* determine whether a function is always inlined or not.

By the way, static should always be used when it applies, because it
also lets the compiler emit non strictly ABI-compliant code, which may
be faster.

-- Alain.

> Just the emit/not emit choice should influence the inlining decision,
> because this in turn influences code size.
>
> Let's say I have this in a translation unit:
>
>    int foo(void) { /* pages of code */ }
>    int bar(void) {
>       int n = foo();
>       /* other stuff */
>    }
>
> I'd expect a compiler to have a conservative inlining mode which
> doesn't inline foo() in this case, to avoid code bloat.
> (Especially since you're almost certain to have foo() calls in other
> translation units, or you would have made it static.)
>
> /Jorgen

[toc] | [prev] | [next] | [standalone]


#28696

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2012-11-27 21:55 +0000
Message-ID<slrnkbadn5.1jc.grahn+nntp@frailea.sa.invalid>
In reply to#28638
On Sun, 2012-11-25, Alain Ketterlin wrote:
> Jorgen Grahn <grahn+nntp@snipabacken.se> writes:
>
> [...]
>>> static will make the compiler not emit code when all calls have been
>>> inlined. It should not influence the inlining decision.
>>
>> Why not?
>
> You're right, my phrasing was misleading. What I meant was: static will
> not *by itself* determine whether a function is always inlined or not.

Ah, good.

> By the way, static should always be used when it applies, because it
> also lets the compiler emit non strictly ABI-compliant code, which may
> be faster.

I think I see gcc do this even for non-static functions -- they may
get one ABI-compliant entry point and one tuned for local callers. The
latter presumably skips some register saving or something.  (But I
don't know x86 assembly well enough to be sure about this!)

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#28658

From"christian.bau" <christian.bau@cbau.wanadoo.co.uk>
Date2012-11-26 04:16 -0800
Message-ID<c2857271-6c38-4e2f-8af6-28a47f929bf8@p17g2000vbn.googlegroups.com>
In reply to#28617
On Nov 24, 4:17 pm, Alain Ketterlin <al...@dpt-info.u-strasbg.fr>
wrote:

> static will make the compiler not emit code when all calls have been
> inlined. It should not influence the inlining decision.

In practice, gcc and clang really like to inline static functions that
are only called from one place - after all, you still have exactly one
copy of the code, so it doesn't seem to hurt. If the function is just
extern, a copy must be kept around for any extern calls, so inlining
doubles the amount of code, and both compilers tend to inline less.
Making the function extern and moving it into a separate file makes it
quite hard for the compiler to inline :-)

The problem with overzealous inlining is that both compilers tend to
produce less good code for large functions with lots of variables. The
same loop inside a small function might run completely in registers,
while as part of a large function it uses variables on the stack and
runs a lot slower.

So what the original poster described is quite possible with gcc and
clang: You add code to a static function that is never called at
runtime. The compiler moves the code into a large function which gets
larger. There are more variables to copy with, and the code for the
large function gets worse.

[toc] | [prev] | [next] | [standalone]


#28660

FromDavid Brown <david@westcontrol.removethisbit.com>
Date2012-11-26 14:13 +0100
Message-ID<Fd6dnWil9-L98S7NnZ2dnUVZ7oSdnZ2d@lyse.net>
In reply to#28658
On 26/11/2012 13:16, christian.bau wrote:
> On Nov 24, 4:17 pm, Alain Ketterlin <al...@dpt-info.u-strasbg.fr>
> wrote:
>
>> static will make the compiler not emit code when all calls have been
>> inlined. It should not influence the inlining decision.
>
> In practice, gcc and clang really like to inline static functions that
> are only called from one place - after all, you still have exactly one
> copy of the code, so it doesn't seem to hurt. If the function is just
> extern, a copy must be kept around for any extern calls, so inlining
> doubles the amount of code, and both compilers tend to inline less.
> Making the function extern and moving it into a separate file makes it
> quite hard for the compiler to inline :-)
>
> The problem with overzealous inlining is that both compilers tend to
> produce less good code for large functions with lots of variables. The
> same loop inside a small function might run completely in registers,
> while as part of a large function it uses variables on the stack and
> runs a lot slower.

That is only true if you compile with low optimisation settings (or with 
older or less sophisticated compilers).  To get good code, it is 
important to give the compiler freedom to generate it's best code - that 
means high optimisation settings (remembering that some settings, such 
as loop unrolling, can lead to slower code due to larger code having 
more cache misses), and either turning off debug information generation, 
or at least picking the most expressive possible debug format (so that 
the compiler does not restrict code generation to suit debugger 
capabilities).

In particular, lifetime analysis and register colouring algorithms 
should allow a great deal of re-use of registers, so that local 
variables are held in registers rather than the stack.  For the most 
part, therefore, code that ran from registers in a non-inlined version 
of a function will still run from registers when it is inlined.

It is possible to help the compiler a bit here, if you have challenging 
code.  Options like "-fweb" and "-frename-registers" in gcc can improve 
the register allocation.  And of course it helps to make sure you use 
all the processor's capabilities - on a PC, use 64-bit rather than 
32-bit to get more registers.

Where large inlining can slow you down is if inner loops get very large, 
and you lose locality - on many processors, short relative jumps are 
faster than big ones, and if your loop gets too big for the fastest 
level of cache, you will slow down.

>
> So what the original poster described is quite possible with gcc and
> clang: You add code to a static function that is never called at
> runtime. The compiler moves the code into a large function which gets
> larger. There are more variables to copy with, and the code for the
> large function gets worse.
>

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web