February 18, 2020
On Tue, Feb 18, 2020 at 09:22:18PM +0000, matheus via Digitalmars-d wrote: [...]
> Just to be clear, I am NOT diminishing any work, I just wasn't aware of these differences, because 20 to 30 or maybe 40% on runtime is something that you can't just ignore.

It depends on your use case.  YMMV, as they say.

IME, the difference is most pronounced for CPU-intensive code where you have a lot of nested constructs, esp. in range-based code with extensive use of UFCS chains.

Some years ago I analysed the assembly output to understand why this is so.  According to my observations, one big factor is that the DMD inliner is rather anemic: it gives up at the slightest complication, thus missing out on what's commonly a domino-effect of optimizations: inlining the innermost function call opens up new optimization opportunities which causes the next outer level to be inlineable, etc., until most of the call stack has been inlined. But stop somewhere in between and you miss out the rest of the entire call chain's worth of optimizations.  In range-based code, most of the method calls are very small, so quite often a long chain of nested calls can be reduced to just a few inlined instructions, so this is where LDC's very aggressive inliner really shines.  In such cases, you can easily see 20-30% almost-guaranteed performance difference, and sometimes I've seen even up to 40%.  I just ran a quick test again, as I posted in another reply, and again I see a >30% performance boost just from using ldc2 instead of dmd.

The LLVM optimizer has been known to optimize entire call chains into the equivalent of a `return constValue;` by executing LLVM bytecode at compile-time to optimize away an entire subtree of function calls into a constant value. DMD's inliner, in comparison, balks at the sight of things as trivial as writing:

	auto myFunc(...) {
		if (cond) return result1;
		return result2;
	}

vs.

	auto myFunc(...) {
		if (cond) return result1;
		else return result2;
	}

so it tends to give up long before the code has been transformed into a state where it can be inlined one level further up the call chain. Thus, an entire domino-chain of optimizations is missed, and you end up with several nested function calls where it could have been reduced to just a few inlined instructions. When this happens in the inner loop, a 30% performance drop is pretty much expected.


> I think that maybe is possible to balance things, like developing with DMD and generate final code with GDC/LDC to get faster runtime, well maybe some problems will happen mixing compilers and final result, but this is something that I will considerate for now on.
[...]

As somebody pointed out, using dmd for development and ldc2 for release build is definitely a viable approach.  Recent LDC releases have been tracking DMD releases very closely, so excepting rare corner cases and bugs, functionality-wise the two compilers should pretty much be on par.

And now that I've learned that ldmd2 doesn't preclude passing LDC-specific flags on the command-line, I might actually just adopt this approach.  (The trouble with different command-line syntaxes is that compilers are not drop-in replacements for each other, which makes supporting multiple compilers in the same build script a pain. Certainly possible, and not even hard, but nonetheless a pain to write and maintain. With ldmd2 I can just standardize on DMD command-line syntax and have everything Just Work(tm). Best of both worlds.)


T

-- 
People demand freedom of speech to make up for the freedom of thought which they avoid. -- Soren Aabye Kierkegaard (1813-1855)
February 18, 2020
On Tuesday, 18 February 2020 at 21:26:14 UTC, H. S. Teoh wrote:
> With `dmd -O -inline`, a typical run is about 25-26 seconds.  With `ldmd2 -O3`, a typical run is about 16-17 seconds.  We're looking at a ~30% increase in performance here

Take care with such numbers - this sounds more like a 50% increase in performance. A speed-up by 4 (300% performance *increase*) results in 1/4th of the runtime, i.e., a runtime *decrease* by 75%.
February 18, 2020
On Tue, Feb 18, 2020 at 10:14:54PM +0000, kinke via Digitalmars-d wrote:
> On Tuesday, 18 February 2020 at 21:26:14 UTC, H. S. Teoh wrote:
> > With `dmd -O -inline`, a typical run is about 25-26 seconds.  With `ldmd2 -O3`, a typical run is about 16-17 seconds.  We're looking at a ~30% increase in performance here
> 
> Take care with such numbers - this sounds more like a 50% increase in performance. A speed-up by 4 (300% performance *increase*) results in 1/4th of the runtime, i.e., a runtime *decrease* by 75%.

Even better then. :-D


T

-- 
"A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..." -- Joshua D. Wachs - Natural Intelligence, Inc.
February 19, 2020
On Tuesday, 18 February 2020 at 20:10:57 UTC, kinke wrote:
> but to me, the DMD *backend* is clearly a dead end in the long run.

Its already at that point for me. PR sit stagnant for so long waiting on Walter by the time he looks at it it no longer compiles because of changes to the compiler, then proceeds to complain that it doesn't compile. It did 6 months ago.
February 18, 2020
On 2/18/2020 1:52 PM, H. S. Teoh wrote:
> DMD's inliner, in comparison, balks at the sight of
> things as trivial as writing:
> 
> 	auto myFunc(...) {
> 		if (cond) return result1;
> 		return result2;
> 	}
> 
> vs.
> 
> 	auto myFunc(...) {
> 		if (cond) return result1;
> 		else return result2;
> 	}

With:

  int fooa(int a, int b, int c) {
    if (a)
	return b;
    return c;
  }

  int foob(int a, int b, int c) {
    if (a)
	return b;
    else
	return c;
  }

  int test(int a, int b, int c) {
    return fooa(a, b, c) + foob(a, b, c);
  }

the generated code for test() compiled with -inline -O is:

                push    EAX
                cmp     dword ptr 0Ch[ESP],0
                je      LE
                mov     EAX,8[ESP]
                jmp short       L11
  LE:           mov     EAX,[ESP]
  L11:          add     EAX,EAX
                pop     ECX
                ret     8

so it is inlining both forms. If you do have trivial functions that aren't being inlined, please let me know. Thanks!
February 19, 2020
On Wednesday, 19 February 2020 at 05:42:19 UTC, Walter Bright wrote:

> so it is inlining both forms. If you do have trivial functions that aren't being inlined, please let me know. Thanks!

Anything with a 'switch':

void foo() {
    switch(true) {
        default:
    }
}
February 19, 2020
On 2/18/20 11:00 PM, jxel wrote:
>>> IMO you are wrong if you think that dropping dmd will increase man power in ldc/gdc land.
> 
> Who said that? That's your misinterpretation.

Experience says that again and again. If someone contributes to project A why he should start contributing to project B if project A would be completed? He can easily start contributing to project C, D etc. You have no warranty at all.

February 19, 2020
On Wednesday, 19 February 2020 at 07:27:39 UTC, drug wrote:
> On 2/18/20 11:00 PM, jxel wrote:
>>>> IMO you are wrong if you think that dropping dmd will increase man power in ldc/gdc land.
>> 
>> Who said that? That's your misinterpretation.
>
> Experience says that again and again. If someone contributes to project A why he should start contributing to project B if project A would be completed? He can easily start contributing to project C, D etc. You have no warranty at all.

I think there's been a misunderstanding in this branch of the conversation. Dropping DMD means nothing... the front end is shared between all compilers after all.
February 19, 2020
On 2020-02-17 20:44, Walter Bright wrote:

> Anyhow, do you want to take a look at the dwarf output and see what's different? The dumpobj tool will pretty-print it.

I added the output of `dwarfdump` to the issue [1], both of DMD and LDC. I also extracted the actual differences in a separate comment [2].

[1] https://issues.dlang.org/show_bug.cgi?id=18527
[2] https://issues.dlang.org/show_bug.cgi?id=18527#c5

-- 
/Jacob Carlborg
February 19, 2020
On Wednesday, 19 February 2020 at 07:27:39 UTC, drug wrote:
> On 2/18/20 11:00 PM, jxel wrote:
>>>> IMO you are wrong if you think that dropping dmd will increase man power in ldc/gdc land.
>> 
>> Who said that? That's your misinterpretation.
>
> Experience says that again and again. If someone contributes to project A why he should start contributing to project B if project A would be completed? He can easily start contributing to project C, D etc. You have no warranty at all.

Like I said, that's your misinterpretation, read the first paragraph.