www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - inlining or not inlining...

reply spir <denis.spir gmail.com> writes:
Hello,

Walter states that inline annotations are useless, since programmers cannot 
generally know which function /should/ be inlined --depending on a variety of 
factors, inlining may in fact be counter-productive.
I totally agree, even more after having (superficially) explored the topic 
(mainly in LLVM docs). This point of view addresses one face of the question: 
namely when a given piece of code will be "factored out" into a separate 
function in any case, and we just wish it could be inlined.

What if instead we wish this piece code inline in any case, even at the price 
of code duplication when it's used by several functions. The point is then 
different: we want to know whether the compiler will inline it, else we do it 
ourselves.

If the compiler does, we are free to write the source in the optimal form for 
clarity; else, we are left and doing our best to prevent code obfuscation. This 
issue often happens to me, maybe, because I have high expectations on clarity, 
so that I tend to make functions for anything conceptually representing a whole 
task, even if tiny, even if used only by a single client func. (Structured 
programming is before all, for me, a tool for clarity, not to avoid code dup.)

Thus, at best, we would need to know a bit about criteria used by the compiler 
for deciding whether to inline or not; provided a doc explaining this is at all 
readable by people who do not have the compiler-writer gene.
Aside that, let us imagine an inline annotation beeing, not a request for 
inlining, but a request for compiler warning emission when inlining would not 
be applied to a given annotated func. Then, programmers would at least know, 
beeing thus able to choose on an informed basis.
Complement to that may be a little (and hopefully clear) how-to guide on "best 
chances to get a func inlined". This howto would start by describing most 
common and/or most critical criteria for the compiler to /not/ inline a given 
func. Then, a short set of negative & positive examples actually generating or 
not the fatal warning.
As a nice side-effect, such a doc may help & make clear some schemes of 
(in)efficiency, in general, even for an inlined piece of code. (*)

Denis

By the way, I would love a [rather big] tutorial on efficiency -- what do you 
think?
-- 
_________________
vita es estrany
spir.wikidot.com
Feb 09 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"spir" <denis.spir gmail.com> wrote in message 
news:mailman.1420.1297253687.4748.digitalmars-d puremagic.com...
 By the way, I would love a [rather big] tutorial on efficiency -- what do 
 you think?

That would be great. Funny timing on your mentioning that, though: I just noticed today that one of my D programs appears to run half as fast when compiled with "-release -O" as it does with "-debug". And no, that's not a typo or a juxtaposition. Haven't really dug into the matter, though.
Feb 09 2011
prev sibling next sibling parent reply Trass3r <un known.com> writes:
 This howto would start by describing most common and/or most critical criteria
for the compiler to /not/ inline a given func.

Well if I read the code correctly: - inline assembler - variadic functions (string s, ...) - synchronized - imported functions - functions with closure vars - virtual functions that aren't final - functions with out, ref or static array parameters - functions with more than 250 elementary expressions
Feb 09 2011
parent Trass3r <un known.com> writes:
At least back in 2010:
http://www.digitalmars.com/d/archives/digitalmars/D/learn/Is_there_a_way_to_get_a_list_of_functions_that_get_inlined_by_dmd_18798.html#N18810
Feb 09 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/09/2011 03:53 PM, Trass3r wrote:
 This howto would start by describing most common and/or most critical criteria
for the compiler to /not/ inline a given func.

Well if I read the code correctly: - inline assembler - variadic functions (string s, ...) - synchronized - imported functions - functions with closure vars - virtual functions that aren't final - functions with out, ref or static array parameters - functions with more than 250 elementary expressions

Very interesting. What do you think about the compiler telling "Function f in module m not inlined"? Guess it would (just) need a flag 'inliningRequested' set by the parser in whatever structure represents a func. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 09 2011
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 09/02/2011 12:14, spir wrote:
 Hello,

 Walter states that inline annotations are useless, since programmers cannot
generally know
 which function /should/ be inlined --depending on a variety of factors,
inlining may in
 fact be counter-productive.

I hate not being able to force functions to be inline. A consequence is that you can't fully interface certain APIs without an extra .lib over what would be needed in C(++). Stewart.
Feb 10 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
Stewart Gordon wrote:
 On 09/02/2011 12:14, spir wrote:
 Hello,

 Walter states that inline annotations are useless, since programmers 
 cannot generally know
 which function /should/ be inlined --depending on a variety of 
 factors, inlining may in
 fact be counter-productive.

I hate not being able to force functions to be inline. A consequence is that you can't fully interface certain APIs without an extra .lib over what would be needed in C(++).

You cannot force inlining in C(++) either. The inline keyword is only a suggestion. I'm not understanding your last comment that a .lib would be required. That's not correct, as since you're supplying the full source anyway (needed for inlining), just compile in that source from the command line. No lib step is needed.
Feb 10 2011
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
so wrote:
 You cannot force inlining in C(++) either. The inline keyword is only 
 a suggestion.

 I'm not understanding your last comment that a .lib would be required. 
 That's not correct, as since you're supplying the full source anyway 
 (needed for inlining), just compile in that source from the command 
 line. No lib step is needed.

Hinting wasn't enough, every major implementation have a forceinline extension now. So you know if something you asked is inlined or not.

There are all kinds of extensions popular in C++, but they are not part of Standard C++.
Feb 11 2011
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
Jonathan M Davis wrote:
 Regardless, I would _hope_ that the compiler would be smart enough to make 
 intelligent choices about inlining. That's probably one of those areas that
can 
 always be improved however.

I agree completely. All compilers could use better register allocation algorithms, too.
Feb 11 2011
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 11/02/2011 06:35, Walter Bright wrote:
<snip>
 I hate not being able to force functions to be inline. A consequence is that
you can't
 fully interface certain APIs without an extra .lib over what would be needed
in C(++).

You cannot force inlining in C(++) either. The inline keyword is only a suggestion.

But is the inline keyword guaranteed to prevent a duplicate symbol error at link time when multiple modules contain this same function after preprocessing?
 I'm not understanding your last comment that a .lib would be required. That's
not correct,
 as since you're supplying the full source anyway (needed for inlining), just
compile in
 that source from the command line. No lib step is needed.

OK, so a .lib isn't strictly necessary, a .obj will do. But for an example of what I'm on about, consider the many #define macros in the C headers of the Windows API. In D, these become functions, and you can't tell the compiler to inline them. Therefore you have to compile the Windows API bindings as modules in their own right, and then link them in, whereas in C(++) you need only to compile and link your own source files (along with a few standard Windows .libs). Consequently, all these functions might end up in the .exe even though they are never used, either because the application code never uses them or because the compiler has inlined them where they are used. Stewart.
Feb 15 2011
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
spir wrote:
 Thus, at best, we would need to know a bit about criteria used by the 
 compiler for deciding whether to inline or not; provided a doc 
 explaining this is at all readable by people who do not have the 
 compiler-writer gene.
 Aside that, let us imagine an inline annotation beeing, not a request 
 for inlining, but a request for compiler warning emission when inlining 
 would not be applied to a given annotated func. Then, programmers would 
 at least know, beeing thus able to choose on an informed basis.
 Complement to that may be a little (and hopefully clear) how-to guide on 
 "best chances to get a func inlined". This howto would start by 
 describing most common and/or most critical criteria for the compiler to 
 /not/ inline a given func. Then, a short set of negative & positive 
 examples actually generating or not the fatal warning.
 As a nice side-effect, such a doc may help & make clear some schemes of 
 (in)efficiency, in general, even for an inlined piece of code. (*)

While in isolation that's a good idea, how far should it be taken? Should the compiler emit information on which variables wound up in which registers, and why? What about other of the myriad of compiler optimizations? Also, if you're willing to look at the assembler output of the compiler, it's pretty trivial to see if a function was inlined or not. If you're interested in optimizing at that level, I think it would make sense to get familiar with the asm output.
 By the way, I would love a [rather big] tutorial on efficiency -- what 
 do you think?

My advice is to start with -cov and -profile.
Feb 10 2011
next sibling parent Brad Roberts <braddr puremagic.com> writes:
On 2/10/2011 10:53 PM, so wrote:
 While in isolation that's a good idea, how far should it be taken? Should the
compiler emit information on which
 variables wound up in which registers, and why? What about other of the myriad
of compiler optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control? A few times i have seen comparisons here to similar languages and in most of them the inlining was the reason (only) for the inferior performance. I agree it would be awesome if the compilers had the ability to chose the best method, but comparisons show sometimes the opposite, i don't know maybe they are hand-picked for some reason.

Nope.. that'd be choosing the 'right' algorithm.
Feb 10 2011
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On 2/10/2011 11:14 PM, so wrote:
 On Fri, 11 Feb 2011 08:56:07 +0200, Brad Roberts <braddr puremagic.com> wrote:
 
 On 2/10/2011 10:53 PM, so wrote:
 While in isolation that's a good idea, how far should it be taken? Should the
compiler emit information on which
 variables wound up in which registers, and why? What about other of the myriad
of compiler optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control? A few times i have seen comparisons here to similar languages and in most of them the inlining was the reason (only) for the inferior performance. I agree it would be awesome if the compilers had the ability to chose the best method, but comparisons show sometimes the opposite, i don't know maybe they are hand-picked for some reason.

Nope.. that'd be choosing the 'right' algorithm.

Heh, yeh after that.

After that it becomes heavily dependent on what the bottle neck is. It's rare that I've felt the need to mess with inlining. But I'm sure this sort of thing is also highly variable based on type of applications, code style, language, etc.
Feb 10 2011
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
so wrote:
 While in isolation that's a good idea, how far should it be taken? 
 Should the compiler emit information on which variables wound up in 
 which registers, and why? What about other of the myriad of compiler 
 optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control?

No, not even close. The first step is figure out where your program is slow, and then why it is slow. For example, if it is slow because foo() is being called 1,000,000 times, you'll get a one thousand times speedup if you can tweak your algorithms so that it is only called 1,000 times.
 A few times i have seen comparisons here to similar languages and in 
 most of them the inlining was the reason (only) for the inferior 
 performance.
 I agree it would be awesome if the compilers had the ability to chose 
 the best method, but comparisons show sometimes the opposite, i don't 
 know maybe they are hand-picked for some reason.

Certainly, the inliner in dmd can be improved.
Feb 11 2011
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On 2/11/2011 12:37 AM, Walter Bright wrote:
 so wrote:
 While in isolation that's a good idea, how far should it be taken? Should the
compiler emit information on which
 variables wound up in which registers, and why? What about other of the myriad
of compiler optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control?

No, not even close. The first step is figure out where your program is slow, and then why it is slow. For example, if it is slow because foo() is being called 1,000,000 times, you'll get a one thousand times speedup if you can tweak your algorithms so that it is only called 1,000 times.
 A few times i have seen comparisons here to similar languages and in most of
them the inlining was the reason (only)
 for the inferior performance.
 I agree it would be awesome if the compilers had the ability to chose the best
method, but comparisons show sometimes
 the opposite, i don't know maybe they are hand-picked for some reason.

Certainly, the inliner in dmd can be improved.

Improving the inline is one of the many itches I intend to scratch at some point. I did some a while back to get my feet wet. I'll get back to it again at some point. Currently it only does the really easy stuff, and that's clearly not good enough in the long run.
Feb 11 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 While in isolation that's a good idea, how far should it be taken? Should the 
 compiler emit information on which variables wound up in which registers, and 
 why? What about other of the myriad of compiler optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start. With CommonLisp compiler when you compile with max optimization levels the compiler gives many comments that explain why it isn't optimizing something, including some forms of inlining, see for example: http://shootout.alioth.debian.org/u32/program.php?test=fasta&lang=sbcl&id=3 Part of the comments: ; --> CEILING MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL FUNCTION IF VALUES 1+ ; ==> ; (+ SB-C::TRU 1) ; ; note: forced to do GENERIC-+ (cost 10) ; unable to do inline fixnum arithmetic (cost 1) because: ; The first argument is a INTEGER, not a FIXNUM. ; The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES FIXNUM &REST T). ; unable to do inline fixnum arithmetic (cost 2) because: ; The first argument is a INTEGER, not a FIXNUM. ; The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES FIXNUM &REST T). ; etc. Another similar kind of useful notes from the compiler: http://d.puremagic.com/issues/show_bug.cgi?id=5070 Bye, bearophile
Feb 11 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
bearophile wrote:
 While in isolation that's a good idea, how far should it be taken? Should the 
 compiler emit information on which variables wound up in which registers, and 
 why? What about other of the myriad of compiler optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start.

Register allocation is far more important than inlining. Why not give information about why a variable was not enregistered?
Feb 11 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 bearophile wrote:
 While in isolation that's a good idea, how far should it be taken? Should the 
 compiler emit information on which variables wound up in which registers, and 
 why? What about other of the myriad of compiler optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start.

Register allocation is far more important than inlining. Why not give information about why a variable was not enregistered?

Some answers: - I am not asking for this information because it is harder to use for me. If a function was inlined or not is simpler to use for me. - In my D1 code I have found two or more problems caused by failed inlining. So this is of my interest. - If you want to optionally give the register information to the programmer, then do it. I am not going to stop you :-) Some people need this information, like when you implement the little kernels of a very fast FFT. - Register allocation on 32 bit CPUs is not the same as on 64 bit ones. On 64 bit you have many more registers (and you have SSE registers, and now AVX too), so in many situations the register pressure is lower. - There are two groups of register allocation algorithms. The very fast ones, and the more precise ones. You even have perfect ones. Experience has shown that the difference in runtime performance between the precise algorithm and the perfect ones is often about 5% (this measured on LLVM(. This means that with LLVM you will probably never see a significant improvement of automatic register allocation, because it's as good as it gets, it's kind of a solved problem. In JITs like in the JavaVM you have register allocation algorithms that are less precise but faster. Here there is space for possible future improvements. And then, there are the special situations, like implementing those little FFT kernels, or when you want to compile a functional language like Haskell into assembly. In such situations even the very good automatic register allocation algorithms are not good enough. In this case information about register allocation is useful, but this is a very specialized usage. The need to know about inlining is in my opinion more common. Bye, bearophile
Feb 11 2011
parent Walter Bright <newshound2 digitalmars.com> writes:
bearophile wrote:
 There are two groups of register allocation algorithms. The very
 fast ones, and the more precise ones. You even have perfect ones. Experience
 has shown that the difference in runtime performance between the precise
 algorithm and the perfect ones is often about 5% (this measured on LLVM(.
 This means that with LLVM you will probably never see a significant
 improvement of automatic register allocation, because it's as good as it
 gets, it's kind of a solved problem.

I've seen those papers on "precise" or even "perfect" register allocation. They're only precise within a certain set of assumptions the compiler makes about usage patterns. Those assumptions are, just that, assumptions. For example, assumptions are made about how many times this loop executes relative to that loop. An asm programmer who knows his salt can do a better job, because he knows what the usage patterns are. Of course it's only rarely worth his while to do so, but nevertheless, calling such an algorithm "perfect" is misleading.
Feb 11 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 About inline, note that no-one asks for information on every potentially 
 inlinable func, blindly. But having a way to know that about /this/ func one
is 
 wondering about would be great: just append  inline to it, recompile, et
voilà! 
 you know :-) (provided you can interpret the output, but it's another story)

If that's your purpose then I suggest a name as isInlinable :-) Bye, bearophile
Feb 11 2011
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
spir wrote:
 On 02/11/2011 08:11 PM, Walter Bright wrote:
 bearophile wrote:
 While in isolation that's a good idea, how far should it be taken? 
 Should
 the compiler emit information on which variables wound up in which
 registers, and why? What about other of the myriad of compiler 
 optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start.

Register allocation is far more important than inlining. Why not give information about why a variable was not enregistered?

Because we do not ask for it ;-)

Actually, that is a good reason.
 Joke apart, I would love that too, on tiny test apps indeed. Why not? 
 Since the decision-taking exist (and is certainly well structured around 
 its criteria), why not allow it writing out its "reasoning"?
 
 About inline, note that no-one asks for information on every potentially 
 inlinable func, blindly. But having a way to know that about /this/ func 
 one is wondering about would be great: just append  inline to it, 
 recompile, et voilà! you know :-) (provided you can interpret the 
 output, but it's another story)
 
 <side-note>
 If I were a compiler writer, no doubt my code would hold snippets 
 dedicated to spitting out such information, on need. For myself, as a 
 testing tool to check the code really does what I mean. This is integral 
 part of my coding style. Else, how can I know? Checking the ASM indeed 
 can tell you, but it seems to me far more heavy & complicated than 
 following the trace of a "reasoning", and tells nothing about 
 where/why/how the encoded logic fails.
 Then, if this can be useful to users...
 <side-note>
 
 Denis

Feb 11 2011
prev sibling next sibling parent "JimBob" <jim bob.com> writes:
"Walter Bright" <newshound2 digitalmars.com> wrote in message 
news:ij41q1$1j1q$2 digitalmars.com...
 bearophile wrote:
 While in isolation that's a good idea, how far should it be taken? 
 Should the compiler emit information on which variables wound up in 
 which registers, and why? What about other of the myriad of compiler 
 optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start.

Register allocation is far more important than inlining. Why not give information about why a variable was not enregistered?

Whether either should be left up to the compiler should be down the merits of actually doing so, not on whether the other one is or not. Nobody wants to be able to specify register allocation. At least ive not seen anyone ask for it. So thats an easy decision. It's a feature nobody would use even if it were included. Inlining is completly different. Lots of people want the ability to control it, or at least to be able to be notified when it doesnt happen. You say look at the asm output? So everytime the compiler gets updated, or somthing changes, we dig through how much source/dissambly to check everything is still getting inlined? Or you say that the compiler can make better decision than the programmer? Maybe it can most of the time but even very mature compilers still spit out awful code sometimes. I thought D was supposed to be a pragmatic language? Well maybe that pragmatism should extend to realizing that compilers dont always get it right.
Feb 12 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
so wrote:
 If you are against this reasoning, i don't have any idea why D has 
 inline assembly, which again targets a very small audience.

The inline assembler is soooo much easier to deal with than the miserable, fugly assemblers found on the various systems. The Linux as assembler is designed to crush all the joy out of writing in asm. The Microsoft assemblers change behavior constantly, breaking everything. The inline assembler can't do everything a standalone assembler can, but what it does it does well enough, and is a pleasure (to me) to use.
Feb 13 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 The inline assembler can't do everything a standalone assembler can, but what
it 
 does it does well enough, and is a pleasure (to me) to use.

The D inline assembler has another purpose you have not underlined: it's a didactic tool to learn some assembly without nothing but the normal D compiler. Delphi too allows inline asm, and I know some people that have used just that to learn and use assembly. The evolution of species is not a constant flow of changes. After a period of quick change, species often froze in many of their characteristics, and then they adapt only in a small ways, or in "alternative" ways, while keeping most of their original design. In the meantime new species branch sideways, and most of the actual fundamental changes happen during this side branching. To me something quite similar seems to happen to software technology: people that program in assembly seems furiously attached to ancient ways to use assembly, even if new and new languages and their ecosystems have invented better and better ways to program. There is not much intrinsic in the asm language that forces people to not define and use a good type system on asm instructions to catch programming bugs, to indent asm code well, to use a modern IDE on asm code, and so on. But most asm programmers seem uninterested in those new tools and new possibilities. All this is quite fascinating. Bye, bearophile
Feb 13 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 There is not much intrinsic in the asm language that forces people
 to not define and use a good type system on asm instructions to
 catch programming bugs, to indent asm code well, to use a modern
 IDE on asm code, and so on.

All of this has been done, and caught on to a huge degree. They called that asm+types language "C" (especially Digital Mars C, which has an excellent inline asm; I can't imagine I would have gotten anything done back in the day using the shitty gcc asm). Of course, we've improved upon that even more, and called it "D". If you're writing any large amount assembly today, it is often because you specifically don't want those kind of things because they either get in the way or are just useless for the task at hand. For the parts when such things are desirable, you write it in C and friends.
Feb 13 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 All of this has been done, and caught on to a huge degree.
 They called that asm+types language "C"

This is part of what I was referring to: http://www.cs.cornell.edu/talc/ Bye, bearophile
Feb 13 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
bearophile wrote:
 Walter:
 
 The inline assembler can't do everything a standalone assembler can, but
 what it does it does well enough, and is a pleasure (to me) to use.

The D inline assembler has another purpose you have not underlined: it's a didactic tool to learn some assembly without nothing but the normal D compiler. Delphi too allows inline asm, and I know some people that have used just that to learn and use assembly.

Yes, you're right.
 The evolution of species is not a constant flow of changes. After a period of
 quick change, species often froze in many of their characteristics, and then
 they adapt only in a small ways, or in "alternative" ways, while keeping most
 of their original design. In the meantime new species branch sideways, and
 most of the actual fundamental changes happen during this side branching.
 
 To me something quite similar seems to happen to software technology: people
 that program in assembly seems furiously attached to ancient ways to use
 assembly, even if new and new languages and their ecosystems have invented
 better and better ways to program.
 
 There is not much intrinsic in the asm language that forces people to not
 define and use a good type system on asm instructions to catch programming
 bugs, to indent asm code well, to use a modern IDE on asm code, and so on.
 But most asm programmers seem uninterested in those new tools and new
 possibilities. All this is quite fascinating.

In that vein, it is exceedingly miserable that assemblers do not accept struct declarations in C format. I always have to painstakingly translate them, and double check that all the offsets and alignment are correct. What a pain.
Feb 13 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 Does D's inline asm allow that?

I don't think so (but I don't know what you are able to do with static structs defined outside the asm block).
 "In the same vein", what about a low-level language with (un)named tuples?

I have suggested some kind of annotation to allow D std.typecons.tuple to support structural typing. And I think Andrei has shown some interest on it. Bye, bearophile
Feb 14 2011
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
spir wrote:
 On 02/14/2011 04:42 AM, Walter Bright wrote:
 In that vein, it is exceedingly miserable that assemblers do not 
 accept struct
 declarations in C format. I always have to painstakingly translate 
 them, and
 double check that all the offsets and alignment are correct. What a pain.

Does D's inline asm allow that?

Yes, in that it is aware of declarations in the D code.
Feb 14 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/11/2011 07:53 AM, so wrote:
 While in isolation that's a good idea, how far should it be taken? Should the
 compiler emit information on which variables wound up in which registers, and
 why? What about other of the myriad of compiler optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control? A few times i have seen comparisons here to similar languages and in most of them the inlining was the reason (only) for the inferior performance. I agree it would be awesome if the compilers had the ability to chose the best method, but comparisons show sometimes the opposite, i don't know maybe they are hand-picked for some reason.

I recently read a study using a dozen test cases to compare optimisations performed by 3 C compiler (IIRC: gcc, a win product, and an LLVM one). Very instructive, and even more surprising for me. In every case, some optimsation was done by a compiler that others did not, or conversely. This let me think for a while... how come? Don't compiler authors know, more or less, what kinds or optimisation "tactics" *exist* in given situations? and thus are performed by others. Strange. If this is the case, then the world of programming definitely needs a public knowledge base dedicated to compiler technique, esp. on optimisation. A wiki, indeed. denis -- _________________ vita es estrany spir.wikidot.com
Feb 11 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 People possibly interested in the question of inlining (or more generally 
 factors of (in)efficiency) must start somehow, granted. But making it even
more 
 difficult than necessary, while we all know it is inherently a very complex 
 topic, does not bring much, don't you think?
 In this case, I guess emitting such an information is very easy, since the 
 compiler already needs to compute whether or not to inline. Or am I wrong and 
 overlook a relevant point? On the other side, the feedback brought is
extremely 
 valuable; it allows learning by trial & error, and/or guided by a little howto 
 as evoked above. Both count, and personal experience primes (I guess).

I have added an enhancement request, where you are able to add more comments like those ones: http://d.puremagic.com/issues/show_bug.cgi?id=5563 Bye, bearophile
Feb 11 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/11/2011 08:11 PM, Walter Bright wrote:
 bearophile wrote:
 While in isolation that's a good idea, how far should it be taken? Should
 the compiler emit information on which variables wound up in which
 registers, and why? What about other of the myriad of compiler optimizations?

Inlining is an important optimization, so give this information to the programmer is a good start.

Register allocation is far more important than inlining. Why not give information about why a variable was not enregistered?

Because we do not ask for it ;-) Joke apart, I would love that too, on tiny test apps indeed. Why not? Since the decision-taking exist (and is certainly well structured around its criteria), why not allow it writing out its "reasoning"? About inline, note that no-one asks for information on every potentially inlinable func, blindly. But having a way to know that about /this/ func one is wondering about would be great: just append inline to it, recompile, et voilà! you know :-) (provided you can interpret the output, but it's another story) <side-note> If I were a compiler writer, no doubt my code would hold snippets dedicated to spitting out such information, on need. For myself, as a testing tool to check the code really does what I mean. This is integral part of my coding style. Else, how can I know? Checking the ASM indeed can tell you, but it seems to me far more heavy & complicated than following the trace of a "reasoning", and tells nothing about where/why/how the encoded logic fails. Then, if this can be useful to users... <side-note> Denis -- _________________ vita es estrany spir.wikidot.com
Feb 11 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/11/2011 10:08 PM, bearophile wrote:
 spir:

 About inline, note that no-one asks for information on every potentially
 inlinable func, blindly. But having a way to know that about /this/ func one is
 wondering about would be great: just append  inline to it, recompile, et
voilà!
 you know :-) (provided you can interpret the output, but it's another story)

If that's your purpose then I suggest a name as isInlinable :-)

Fine :-) denis -- _________________ vita es estrany spir.wikidot.com
Feb 11 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 02/14/2011 04:42 AM, Walter Bright wrote:
 In that vein, it is exceedingly miserable that assemblers do not accept struct
 declarations in C format. I always have to painstakingly translate them, and
 double check that all the offsets and alignment are correct. What a pain.

Does D's inline asm allow that? "In the same vein", what about a low-level language with (un)named tuples? Denis -- _________________ vita es estrany spir.wikidot.com
Feb 14 2011
prev sibling next sibling parent so <so so.so> writes:
 You cannot force inlining in C(++) either. The inline keyword is only a  
 suggestion.

 I'm not understanding your last comment that a .lib would be required.  
 That's not correct, as since you're supplying the full source anyway  
 (needed for inlining), just compile in that source from the command  
 line. No lib step is needed.

Hinting wasn't enough, every major implementation have a forceinline extension now. So you know if something you asked is inlined or not.
Feb 10 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday 10 February 2011 22:35:34 Walter Bright wrote:
 Stewart Gordon wrote:
 On 09/02/2011 12:14, spir wrote:
 Hello,
 
 Walter states that inline annotations are useless, since programmers
 cannot generally know
 which function /should/ be inlined --depending on a variety of
 factors, inlining may in
 fact be counter-productive.

<snip> I hate not being able to force functions to be inline. A consequence is that you can't fully interface certain APIs without an extra .lib over what would be needed in C(++).

You cannot force inlining in C(++) either. The inline keyword is only a suggestion.

True. However, IIRC -O3 in gcc forces inlining, so in some cases you _can_ force it (though that's obviously compiler-specific), but forcing inlining with -O3 does it for _everything_, so it's not exactly precision instrument. Regardless, I would _hope_ that the compiler would be smart enough to make intelligent choices about inlining. That's probably one of those areas that can always be improved however. - Jonathan M Davis
Feb 10 2011
prev sibling next sibling parent so <so so.so> writes:
 While in isolation that's a good idea, how far should it be taken?  
 Should the compiler emit information on which variables wound up in  
 which registers, and why? What about other of the myriad of compiler  
 optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control? A few times i have seen comparisons here to similar languages and in most of them the inlining was the reason (only) for the inferior performance. I agree it would be awesome if the compilers had the ability to chose the best method, but comparisons show sometimes the opposite, i don't know maybe they are hand-picked for some reason.
Feb 10 2011
prev sibling next sibling parent so <so so.so> writes:
On Fri, 11 Feb 2011 08:56:07 +0200, Brad Roberts <braddr puremagic.com>  
wrote:

 On 2/10/2011 10:53 PM, so wrote:
 While in isolation that's a good idea, how far should it be taken?  
 Should the compiler emit information on which
 variables wound up in which registers, and why? What about other of  
 the myriad of compiler optimizations?

Isn't Inlining by far the most important (most practical) optimization among those that actually we can control? A few times i have seen comparisons here to similar languages and in most of them the inlining was the reason (only) for the inferior performance. I agree it would be awesome if the compilers had the ability to chose the best method, but comparisons show sometimes the opposite, i don't know maybe they are hand-picked for some reason.

Nope.. that'd be choosing the 'right' algorithm.

Heh, yeh after that.
Feb 10 2011
prev sibling next sibling parent so <so so.so> writes:
 No, not even close. The first step is figure out where your program is  
 slow, and then why it is slow. For example, if it is slow because foo()  
 is being called 1,000,000 times, you'll get a one thousand times speedup  
 if you can tweak your algorithms so that it is only called 1,000 times.

I think we are talking about two different things, i don't mean locating the cause of the bottleneck, it is of course the most logical thing to do. Assume we know the problem, a function that has been reduced to simplest case, still compiler for some reason didn't do the inlining and we need every bit. Wrappers and frequent matrix, vector operations are a very serious examples that inlining is must. Now, it doesn't matter how easy or hard, have could we get around this? This is a great for an annotation.
Feb 11 2011
prev sibling next sibling parent so <so so.so> writes:
 Wrappers and frequent matrix, vector operations are -a- very serious  
 examples that inlining is must. Now, it doesn't matter how easy or hard,  
 -have- +how+ could we get around this?
 This is a great +excuse+ for an annotation.

duh... how hard to synchronize brain, hands and eyes...
Feb 11 2011
prev sibling next sibling parent so <so so.so> writes:
 But I'm sure this sort of thing is also highly variable based on type of  
 applications, code style, language, etc.

Indeed it is, for example you won't hear much complaints from game developers because they rely on GPU for most of the computations these days, but there are other areas where cpu is used intensively, you can be sure just because of this simple issue they won't use D. And the funny part is that it doesn't hurt anyone having this with the specific features D has (annotations), it is a win-win. Also i am not talking about c++ "inline" keyword here, if you go check a few open-source cpu heavy projects, they mostly use compiler specific forced inlines. inline // either inline this or give me an error why you can't / won't.
Feb 11 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/11/2011 07:32 AM, Walter Bright wrote:
 spir wrote:
 Thus, at best, we would need to know a bit about criteria used by the
 compiler for deciding whether to inline or not; provided a doc explaining
 this is at all readable by people who do not have the compiler-writer gene.
 Aside that, let us imagine an inline annotation beeing, not a request for
 inlining, but a request for compiler warning emission when inlining would not
 be applied to a given annotated func. Then, programmers would at least know,
 beeing thus able to choose on an informed basis.
 Complement to that may be a little (and hopefully clear) how-to guide on
 "best chances to get a func inlined". This howto would start by describing
 most common and/or most critical criteria for the compiler to /not/ inline a
 given func. Then, a short set of negative & positive examples actually
 generating or not the fatal warning.
 As a nice side-effect, such a doc may help & make clear some schemes of
 (in)efficiency, in general, even for an inlined piece of code. (*)

While in isolation that's a good idea, how far should it be taken? Should the compiler emit information on which variables wound up in which registers, and why? What about other of the myriad of compiler optimizations? Also, if you're willing to look at the assembler output of the compiler, it's pretty trivial to see if a function was inlined or not. If you're interested in optimizing at that level, I think it would make sense to get familiar with the asm output.

People possibly interested in the question of inlining (or more generally factors of (in)efficiency) must start somehow, granted. But making it even more difficult than necessary, while we all know it is inherently a very complex topic, does not bring much, don't you think? In this case, I guess emitting such an information is very easy, since the compiler already needs to compute whether or not to inline. Or am I wrong and overlook a relevant point? On the other side, the feedback brought is extremely valuable; it allows learning by trial & error, and/or guided by a little howto as evoked above. Both count, and personal experience primes (I guess). I have actually programmed some pieces of code in ASM (a very long time ago), so I know it is possible for normal people. But the barrier is still very high; and anyway one approach does not prevent the other, instead compiler feedback is very complementary to asm "contemplation" ;-) Don't you think so? Even more, the compiler routine deciding on inlining probably has, at least partly, a form of checklist, so that the compiler could even say /why/... which would help much when decoding asm by giving some hint on /what/ to look for. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 11 2011
prev sibling next sibling parent so <so so.so> writes:
 Register allocation is far more important than inlining. Why not give  
 information about why a variable was not enregistered?

I am sorry Walter but your stance on this more politic than a practical fact, it is not you, sounds like you secured a professorship!. :)
Feb 11 2011
prev sibling next sibling parent so <so so.so> writes:
 Register allocation is far more important than inlining. Why not give  
 information about why a variable was not enregistered?

I am sorry Walter but your stance on this more politic than a practical fact, it is not you, sounds like you secured a professorship!. :)

Now i started to see the reasons of your stance, reading some of the old posts about this you are right directing them to asm output. Because what they ask is doesn't make sense, this is a low level optimization/query and if they can't even find out from asm output (also this is something needs to be queried that way), this is the last of their concerns. Again, you are absolutely right if your reasoning is that things like can_inline please_tell_me_if_you_can is just nonsense. Real issue pops up when you know if compiler is inlining or not but have no say in the decision process. You simply need a mechanism to sometimes state, "i need all i can get here, i know what i am doing, inline and save me a function call cost." And unlike many other low level optimizations this is something we can control. If you are against this reasoning, i don't have any idea why D has inline assembly, which again targets a very small audience.
Feb 11 2011
prev sibling next sibling parent so <so so.so> writes:
 There are all kinds of extensions popular in C++, but they are not part  
 of Standard C++.

That is because if they don't support an extension (where standard failed to provide), people would switch to different compiler that would. If you mean there are many things a language can't possibly cope with, where it could be supported by extensions and inline is one of them, you would be right and i agree on this point completely.
Feb 12 2011
prev sibling next sibling parent so <so so.so> writes:
On Mon, 14 Feb 2011 00:58:48 +0200, Walter Bright  
<newshound2 digitalmars.com> wrote:

 so wrote:
 If you are against this reasoning, i don't have any idea why D has  
 inline assembly, which again targets a very small audience.

The inline assembler is soooo much easier to deal with than the miserable, fugly assemblers found on the various systems. The Linux as assembler is designed to crush all the joy out of writing in asm. The Microsoft assemblers change behavior constantly, breaking everything. The inline assembler can't do everything a standalone assembler can, but what it does it does well enough, and is a pleasure (to me) to use.

That was not my question. I am not against inline asm, quite contrary it is one of the best things in D. I just tried to point out that both should be provided because of similar reasons.
Feb 13 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/14/11, bearophile <bearophileHUGS lycos.com> wrote:
 spir:

 Does D's inline asm allow that?

I don't think so (but I don't know what you are able to do with static structs defined outside the asm block).

I think the asm in DMD is the same one used in DMC, so this page should be helpfull: http://www.digitalmars.com/ctg/ctgInlineAsm.html
Feb 14 2011