Jump to page: 1 2
Thread overview
[Bug 67] New: Imported functions are not inlined.
Mar 22, 2006
d-bugmail
Making sure lightweight inline functions really are lightweight (was: [Bug 67] New: Imported functions are not inlined.)
Mar 22, 2006
Stewart Gordon
Re: Making sure lightweight inline functions really are lightweight (was:
Mar 22, 2006
Dave
Mar 25, 2006
d-bugmail
Mar 25, 2006
Walter Bright
Mar 25, 2006
Deewiant
Mar 26, 2006
Walter Bright
Mar 26, 2006
Deewiant
Mar 26, 2006
Walter Bright
Mar 27, 2006
Kyle Furlong
Bugzilla workflow thoughts
Mar 25, 2006
braddr
Mar 25, 2006
Dave
Mar 25, 2006
d-bugmail
Apr 27, 2006
d-bugmail
March 22, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=67

           Summary: Imported functions are not inlined.
           Product: D
           Version: 0.150
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: P3
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: godaves@yahoo.com


/*
   Compile with -O -inline -release
   This program compares performance of 2 identical functions, one inlined,
    the other not.
   There is about a 7x difference on my system.
*/

import std.stdio, std.date, std.math;

// local copy of std.math.abs()
int abs(int x)
{
return x >= 0 ? x : -x;
}

void main()
{
    int sum = 0;
    d_time s = getUTCtime();
    for(int i = 0; i < 100_000_000; i++)
    {
        sum += std.math.abs(i);
        sum -= std.math.abs(-i);
    }
    d_time e = getUTCtime();
    writefln("std.math.abs(): sum= ",sum,", secs = ",(e -
s)/cast(double)TicksPerSecond);

    d_time tmp = e - s;

    sum = 0;
    s = getUTCtime();
    for(int i = 0; i < 100_000_000; i++)
    {
        sum += .abs(i);
        sum -= .abs(-i);
    }
    e = getUTCtime();
    writefln("local abs():    sum= ",sum,", secs = ",(e -
s)/cast(double)TicksPerSecond);

    writefln("ratio = ", tmp / cast(double)(e - s));
}


-- 

March 22, 2006
d-bugmail@puremagic.com wrote:
> http://d.puremagic.com/bugzilla/show_bug.cgi?id=67
<snip>

This brings me to something I've been thinking lately.

http://www.digitalmars.com/d/pretod.html

states, of replacing C preprocessor macros with such things, "The compiler optimizer will inline it; no efficiency is lost."

But is any compactness lost?

When compiling a module, the compiler has to decide whether to generate object code for every function.  If the function is small enough that the compiler feels it's worth inlining, _and_ the function is private, then indeed, the function doesn't need to exist as a function in the object code.  But what if the function the compiler wants to inline is public?

If the entire program is compiled from scratch in one run of the compiler, then it doesn't matter whether inlining is within or between modules.

But if you're not compiling the whole thing in one go, then things become more complicated.  Of course, the heuristic used to determine whether to inline a function would need to be absolute, and applied equally to code in the module being compiled and to code in imported modules.

But different compilers will have different heuristics, and so if different compilers have been used then there'll be problems.  Moreover, what if some modules have been compiled with -inline and some without? Either could easily happen when using libraries, including Phobos. There are four possibilities:

(a) the function isn't inlined either when defined or being called - just a normal non-inline function
(b) the function is inlined both where defined and where called - in which case it's just like a C #define in this respect
(c) the function is inlined when called, but there is still object code for the function nonetheless
(d) the compiler of the module in which it's defined wants it inline, therefore not generating object code for it, but whatever compiles modules that call the function do want it to be inline

Situation (a) or (b) is obviously the most sensible.  (c) would work, but the result would be code bloat.  Of course, any half-decent linker would do some level of dead code elimination, but there's been some sceptical talk around here on how good they really are.

http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/8200

But (d) would cause the program not to link, and therefore would have to be avoided.

A consequence is that bindings for C APIs that use #defines as inline functions might be compromised by the need to link in a new library and the resulting code bloat.

A possible solution is to have the inline attribute available for if someone wants it, which would force the compiler to inline the function, while not forbidding the compiler to also inline functions as it sees fit....

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
March 22, 2006
In article <dvrt27$1247$1@digitaldaemon.com>, Stewart Gordon says...
>
>d-bugmail@puremagic.com wrote:
>> http://d.puremagic.com/bugzilla/show_bug.cgi?id=67
><snip>
>
>This brings me to something I've been thinking lately.
>
>http://www.digitalmars.com/d/pretod.html
>
<original: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/6769 snipped to shorten>

The code bloat thing may actually not be an issue, believe it or not, because some exe's (not libraries, but the things actually executed) are actually smaller when inlining is done, because futher speed and *size* optimizations can then be done on the inlined code by the backend optimizer. I think DMD has real good hueristics for determining what and what not to inline and I know code size plays *the* major role in that.

See: http://www.digitalmars.com/d/archives/digitalmars/D/31013.html

- Dave


March 25, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=67


unknown@simplemachines.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |unknown@simplemachines.org




------- Comment #1 from unknown@simplemachines.org  2006-03-25 02:32 -------
That's because in inline.c, when checking to see if a function can be inlined, it checks to see if the semantic run has happened yet.  Which makes sense, because that needs to happen to inline it.

Simply adding a semantic3 to Import fixes this (because then imported functions
are get a sematic run), although honestly I'm not sure if that's the right fix.
 It may be a lot slower to do this, and it may certainly have been left out on
purpose.

Maybe it can be sematic3'd only when -inline is passed, if that can work.

Really, I must say, I always expected that this worked and now wonder how much benefit/deteriment it would give if it did.

Thanks,
-[Unknown]


-- 

March 25, 2006
http://d.puremagic.com/bugzilla/show_bug.cgi?id=67





------- Comment #2 from godaves@yahoo.com  2006-03-25 11:45 -------
>That's because in inline.c, when checking to see if a function can be inlined, it checks to see if the semantic run has happened yet.  Which makes sense, because that needs to happen to inline it.
>
>Simply adding a semantic3 to Import fixes this (because then imported functions are get a sematic run), although honestly I'm not sure if that's the right fix.

Good catch! I'll try and find the time to update my copy of the dmd front-end and give it a shot. Given D is performance orientated, this needs to work as people will expect it to.

> It may be a lot slower to do this, and it may certainly have been left out on
>purpose.

Yea, but in any case -inline doesn't have to be used and won't be for most of the code/debug/run cycle, right? The DMD compiler is so fast that even for release builds I can't see this causing a big problem requiring things like "grid compiling" <g>.

If code size is a concern, most of phobos.lib is built w/o -inline right now, and again, it doesn't have to be used if it severly bloats the code. Sometimes inlining can even reduce code size.

>
>Maybe it can be sematic3'd only when -inline is passed, if that can work.
>

If that is the solution, then it shouldn't be a problem to implement because the compiler switches are global.

Hmmm - could semantic3 just be run in inline.c if it has not been run yet (as
in the case of an imported function)? In any case the import and it's contents
will have already had semantic() run during the 1st semantic pass because
Import::semantic() calls Module::semantic() to process all the symbols in that
module, including other imports, so semantic() is always done recursively
before the inline pass. So, those functions should be ready for semantic3()
before the inline pass... Cool!

If the fix is really that easy then there is no reason not to fix this right away. The worst that could happen is that it will flush out problems with -inline that people will eventually encounter anyhow so the sooner the better I think.

>
>Really, I must say, I always expected that this worked and now wonder how much benefit/deteriment it would give if it did.
>

It can make a very big difference for some pretty commonly used imported functions, and it'll be expected by users of every other language that inlines.

I have not run into a case where it makes any executable slower and can't imagine it being a detriment except in the potential/odd case where it does severly bloat the code.

Thanks,
- Dave

>Thanks,
>-[Unknown]


-- 

March 25, 2006
Don't spend time on this bug, I already have it fixed. -Walter


March 25, 2006
Walter Bright wrote:
> Don't spend time on this bug, I already have it fixed. -Walter
> 

Could you marked fixed bugs as FIXED in the Bugzilla? It would make it easy to see how things are progressing, plus someone doesn't have to go through the fixed bugs in Bugzilla every time you post a new DMD changelog.
March 25, 2006
Righto.  I didn't spend much time on it, but it would have been nice if there was some indication in the bugzilla bug that it was fixed.

Do we have anyone who is expected to verify bugs?  Typically, from all the bugzilla's I've worked with, bugs are marked fixed and, ideally, verified (or reopened) as such by QA before a release is made.

Maybe this is too much red tape, but it would seem logical to QA the bugs after releases, at least.  IMHO.

Thanks,
-[Unknown]


> Don't spend time on this bug, I already have it fixed. -Walter 
> 
> 
March 25, 2006
In article <e0408v$ba5$1@digitaldaemon.com>, Walter Bright says...
>
>Don't spend time on this bug, I already have it fixed. -Walter

Please, anyone working on a bug, be it Walter or one of us out here in the peanut gallery, be sure to move the state of a bug from NEW to ASSIGNED and make sure it's assigned to you.

It's helpful to know that someone else is spending time diagnosing a bug so others can either talk with that person first or divert their attention elsewhere.

Not that there's a lot of redundant work going on, but there's few enough of with little enough time that it'd be good to make that time as effective as it can be.

from Unknown:
> Do we have anyone who is expected to verify bugs?  Typically, from all the bugzilla's I've worked with, bugs are marked fixed and, ideally, verified (or reopened) as such by QA before a release is made.
> 
> Maybe this is too much red tape, but it would seem logical to QA the bugs after releases, at least.  IMHO.

It'd be nice if the original filer could take on that job.  I'll try to do some as time permits.  That said, for most of the projects I've been a part of, resolved is pretty much a terminal condition unless someone notices a problem or disagrees with the resolution and reopens, which is pretty rare.

Later,
Brad


March 25, 2006
In article <e0408v$ba5$1@digitaldaemon.com>, Walter Bright says...
>
>Don't spend time on this bug, I already have it fixed. -Walter
>

Nice!! Thanks Walter!

- Dave


« First   ‹ Prev
1 2