digitalmars.D - How to stop DMD from exploding the executable file size?
- ryuukk_ (11/11) Aug 30 2022 Having this simple code makes the executable gigantic!
- ryuukk_ (16/16) Aug 30 2022 ```
- solidstate1991 (2/18) Sep 01 2022 LDC has way better optimization features, so it's kinda expected.
- H. S. Teoh (9/29) Sep 01 2022 Yep. LDC is my go-to compiler for release builds. I use dmd for
- Bastiaan Veelo (8/37) Sep 02 2022 LDC is great, but note that the object files are equally large
- H. S. Teoh (9/23) Aug 30 2022 Which version of dmd are you using? I tried to compile the above code
- ryuukk_ (3/28) Aug 30 2022 dmd --version prints: `DMD32 D Compiler v2.100.1`
- H. S. Teoh (8/20) Aug 30 2022 [...]
- max haughton (5/16) Sep 02 2022 You really shouldn't have structs this big unless absolutely
- ryuukk_ (12/32) Sep 02 2022 My use case should not makes us blind about the issue DMD is
- ryuukk_ (5/5) Sep 02 2022 Just look: https://i.imgur.com/5JheSIA.png
- H. S. Teoh (8/17) Sep 02 2022 Somebody already pointed out, it's LDC's linker that's eliminating the
- Don Allen (6/11) Sep 02 2022 Working. Building us great stuff that he gives to all of us free.
- max haughton (33/67) Sep 02 2022 If this is what stops them from using D they're using it as a toy
- ryuukk_ (3/3) Sep 05 2022 I went ahead and sent a PR:
Having this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainable
Aug 30 2022
``` $ ldc2 -m64 app.d $ ll total 4545 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 453120 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4195865 Aug 31 00:57 app.obj ``` ``` $ dmd -m64 app.d $ ll total 8617 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 4623872 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4196322 Aug 31 00:57 app.obj ```
Aug 30 2022
On Tuesday, 30 August 2022 at 22:58:44 UTC, ryuukk_ wrote:``` $ ldc2 -m64 app.d $ ll total 4545 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 453120 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4195865 Aug 31 00:57 app.obj ``` ``` $ dmd -m64 app.d $ ll total 8617 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 4623872 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4196322 Aug 31 00:57 app.obj ```LDC has way better optimization features, so it's kinda expected.
Sep 01 2022
On Thu, Sep 01, 2022 at 10:15:03PM +0000, solidstate1991 via Digitalmars-d wrote:On Tuesday, 30 August 2022 at 22:58:44 UTC, ryuukk_ wrote:Yep. LDC is my go-to compiler for release builds. I use dmd for development because the turnaround time is faster, but I also don't care about performance/executable size when using dmd. For release builds when I *do* care about those things, I use LDC; dmd isn't even on my radar for that. T -- Amateurs built the Ark; professionals built the Titanic.``` $ ldc2 -m64 app.d $ ll total 4545 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 453120 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4195865 Aug 31 00:57 app.obj ``` ``` $ dmd -m64 app.d $ ll total 8617 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 4623872 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4196322 Aug 31 00:57 app.obj ```LDC has way better optimization features, so it's kinda expected.
Sep 01 2022
On Thursday, 1 September 2022 at 22:31:50 UTC, H. S. Teoh wrote:On Thu, Sep 01, 2022 at 10:15:03PM +0000, solidstate1991 via Digitalmars-d wrote:LDC is great, but note that the object files are equally large for both compilers. Apparently it is the linker that should be attributed the size reduction. Which leads me to wonder what the main function looks like, because it might have removed the entire initialisation as dead code… It would have been better if OP would have posted complete code. — Bastiaan.On Tuesday, 30 August 2022 at 22:58:44 UTC, ryuukk_ wrote:Yep. LDC is my go-to compiler for release builds. I use dmd for development because the turnaround time is faster, but I also don't care about performance/executable size when using dmd. For release builds when I *do* care about those things, I use LDC; dmd isn't even on my radar for that. T``` $ ldc2 -m64 app.d $ ll total 4545 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 453120 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4195865 Aug 31 00:57 app.obj ``` ``` $ dmd -m64 app.d $ ll total 8617 -rw-r--r-- 1 ryuukk 197121 69 Aug 31 00:57 app.d -rwxr-xr-x 1 ryuukk 197121 4623872 Aug 31 00:57 app.exe* -rw-r--r-- 1 ryuukk 197121 4196322 Aug 31 00:57 app.obj ```LDC has way better optimization features, so it's kinda expected.
Sep 02 2022
On Tue, Aug 30, 2022 at 10:51:46PM +0000, ryuukk_ via Digitalmars-d wrote:Having this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableWhich version of dmd are you using? I tried to compile the above code with 2.098 (old git master) and the total executable size is only 900KB. I remember about a year or two ago there was a bug where dmd would generate 1024 * 1024 store instructions to initialize the array, but I just checked the disassembly, it's now a rep stos, which is very small. T -- Life is unfair. Ask too much from it, and it may decide you don't deserve what you have now either.
Aug 30 2022
On Tuesday, 30 August 2022 at 23:05:16 UTC, H. S. Teoh wrote:On Tue, Aug 30, 2022 at 10:51:46PM +0000, ryuukk_ via Digitalmars-d wrote:dmd --version prints: `DMD32 D Compiler v2.100.1` It's on Windows, maybe that problem is windows specific?Having this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableWhich version of dmd are you using? I tried to compile the above code with 2.098 (old git master) and the total executable size is only 900KB. I remember about a year or two ago there was a bug where dmd would generate 1024 * 1024 store instructions to initialize the array, but I just checked the disassembly, it's now a rep stos, which is very small. T
Aug 30 2022
On Tue, Aug 30, 2022 at 11:09:55PM +0000, ryuukk_ via Digitalmars-d wrote:On Tuesday, 30 August 2022 at 23:05:16 UTC, H. S. Teoh wrote:[...][...]Which version of dmd are you using? I tried to compile the above code with 2.098 (old git master) and the total executable size is only 900KB. I remember about a year or two ago there was a bug where dmd would generate 1024 * 1024 store instructions to initialize the array, but I just checked the disassembly, it's now a rep stos, which is very small.dmd --version prints: `DMD32 D Compiler v2.100.1` It's on Windows, maybe that problem is windows specific?Possibly, Windows uses a different backend path (obviously). Try to look at the disassembly to see if it's the abovementioned problem? T -- If blunt statements had a point, they wouldn't be blunt...
Aug 30 2022
On Tuesday, 30 August 2022 at 22:51:46 UTC, ryuukk_ wrote:Having this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableYou really shouldn't have structs this big unless absolutely necessary. The thing being elided is the initializer and pointer bitmap for the runtime to use.
Sep 02 2022
On Friday, 2 September 2022 at 17:53:51 UTC, max haughton wrote:On Tuesday, 30 August 2022 at 22:51:46 UTC, ryuukk_ wrote:My use case should not makes us blind about the issue DMD is having I tested with both C and Zig, and they both produce small executable If DMD can do it on linux, there is no reason it can't do it on windows, if LDC can do it for both I want to promote D, i can't promote D if i tell people "yeah but X, Y, Z, then you should go with X, when Z, and when stars are aligned, maybe" It just feels bad; and the list of things that feels bad starts to stack up to a point it becomes sadHaving this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableYou really shouldn't have structs this big unless absolutely necessary. The thing being elided is the initializer and pointer bitmap for the runtime to use.
Sep 02 2022
Just look: https://i.imgur.com/5JheSIA.png 5mb for DMD 200kb for LDC Both release build It is very sad, what is walter doing?
Sep 02 2022
On Sat, Sep 03, 2022 at 12:51:09AM +0000, ryuukk_ via Digitalmars-d wrote:Just look: https://i.imgur.com/5JheSIA.png 5mb for DMD 200kb for LDC Both release build It is very sad, what is walter doing?Somebody already pointed out, it's LDC's linker that's eliminating the excess weight. You can prove this yourself by using `dmd -c` and then linking the object files yourself, supplying additional LTO options to discard unreferenced sections. T -- The diminished 7th chord is the most flexible and fear-instilling chord. Use it often, use it unsparingly, to subdue your listeners into submission!
Sep 02 2022
On Saturday, 3 September 2022 at 00:51:09 UTC, ryuukk_ wrote:Just look: https://i.imgur.com/5JheSIA.png 5mb for DMD 200kb for LDC Both release build It is very sad, what is walter doing?Working. Building us great stuff that he gives to all of us free. If the dmd executables are too large for you, use ldc for release builds. Or you can get smaller release builds with dmd by linking the object files yourself. I don't understand why you are still complaining.
Sep 02 2022
On Saturday, 3 September 2022 at 00:49:36 UTC, ryuukk_ wrote:On Friday, 2 September 2022 at 17:53:51 UTC, max haughton wrote:If this is what stops them from using D they're using it as a toy - it's a completely nonsensical pattern 99% of the time. Huge structs usually imply a lack of understanding, for example you could easily blow up the stack. I will at very least try and fix this in dmd, it's just the object emission code being overly conservative (ldc will emit the initializer if you do something that actually needs it), but if this is what stops them using D I would be very skeptical. C doesn't even have struct default-initializers. In reality, the stars have to align the other way - we have lots of people writing D code every day, some of which might not be entirely sure what an object file even is, 99% of the time this kind of stuff just doesn't matter. In line with the above statement, the actual answer here is to try and compress the big initializers rather than faff around with whether they are used or not - should the compiler focus on dead code elimination rather than optimizing the stuff that actually runs? Most of these initializers will be zero, god forbid someone does statically allocate their tensor in a structure potentially we can give them a speed/size tradeoff. Everyone making a living out of D's workflow that I'm aware of is prototype with dmd, ship with ldc or gdc. This should be enshrined in the toolchain, it is not currently but maybe it will be sooner rather than later. I do like small binaries but I can count on 1 hand the number of times it's seemed important and on zero hands the number of time it's actually mattered in practice. If it, in your estimation, does make it a difference it may be of note that PGO can make the inlining much more intelligent and thus save you potentially even double digit percentages of the non-PGO build's size.On Tuesday, 30 August 2022 at 22:51:46 UTC, ryuukk_ wrote:My use case should not makes us blind about the issue DMD is having I tested with both C and Zig, and they both produce small executable If DMD can do it on linux, there is no reason it can't do it on windows, if LDC can do it for both I want to promote D, i can't promote D if i tell people "yeah but X, Y, Z, then you should go with X, when Z, and when stars are aligned, maybe" It just feels bad; and the list of things that feels bad starts to stack up to a point it becomes sadHaving this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableYou really shouldn't have structs this big unless absolutely necessary. The thing being elided is the initializer and pointer bitmap for the runtime to use.
Sep 02 2022
On Saturday, 3 September 2022 at 01:59:56 UTC, max haughton wrote:On Saturday, 3 September 2022 at 00:49:36 UTC, ryuukk_ wrote:It contributes, and give them argumentsOn Friday, 2 September 2022 at 17:53:51 UTC, max haughton wrote:If this is what stops them from using D they're using it as a toy - it's a completely nonsensical pattern 99% of the time. Huge structs usually imply a lack of understanding, for example you could easily blow up the stack.On Tuesday, 30 August 2022 at 22:51:46 UTC, ryuukk_ wrote:My use case should not makes us blind about the issue DMD is having I tested with both C and Zig, and they both produce small executable If DMD can do it on linux, there is no reason it can't do it on windows, if LDC can do it for both I want to promote D, i can't promote D if i tell people "yeah but X, Y, Z, then you should go with X, when Z, and when stars are aligned, maybe" It just feels bad; and the list of things that feels bad starts to stack up to a point it becomes sadHaving this simple code makes the executable gigantic! ```D struct Big { int[1024 * 1024] big = 0; } Big big; ``` Only with DMD, LDC produces a tiny executable Is there a flag available to fix this behavior? it's not sustainableYou really shouldn't have structs this big unless absolutely necessary. The thing being elided is the initializer and pointer bitmap for the runtime to use.I will at very least try and fix this in dmd, it's just the object emission code being overly conservative (ldc will emit the initializer if you do something that actually needs it), but if this is what stops them using D I would be very skeptical. C doesn't even have struct default-initializers.If LDC did it, DMD can do it, specially if it can already do it in linuxIn reality, the stars have to align the other way - we have lots of people writing D code every day, some of which might not be entirely sure what an object file even is, 99% of the time this kind of stuff just doesn't matter.Assumptions, we have to stop with assuming what people like, and do things the right way We have to stop putting the burden on the usersIn line with the above statement, the actual answer here is to try and compress the big initializers rather than faff around with whether they are used or not - should the compiler focus on dead code elimination rather than optimizing the stuff that actually runs? Most of these initializers will be zero, god forbid someone does statically allocate their tensor in a structure potentially we can give them a speed/size tradeoff. Everyone making a living out of D's workflow that I'm aware of is prototype with dmd, ship with ldc or gdc. This should be enshrined in the toolchain, it is not currently but maybe it will be sooner rather than later. I do like small binaries but I can count on 1 hand the number of times it's seemed important and on zero hands the number of time it's actually mattered in practice. If it, in your estimation, does make it a difference it may be of note that PGO can make the inlining much more intelligent and thus save you potentially even double digit percentages of the non-PGO build's size.This is a DMD problem, i am a user, my expectation is it should produce a non bloated executable, that's it, as a user i think that's fair to expect that from a compiler that produce native executables And i show you the release build, on debug it is worse, building 10+mbs files constantly, it'll worn the disk, and it makes file transfer painfully slow over the net Again, i am a user, not a compiler person
Sep 05 2022
Thanks to Herringway on IRC, he made me check dmd/ldc linker invocation and check the difference LDC seem to add: ``` /OPT:REF /OPT:ICF ``` Adding both and now DMD produce small file! (1mb vs 10mb before) Can we have them enabled by default?
Sep 05 2022
On Monday, 5 September 2022 at 17:31:10 UTC, ryuukk_ wrote:This is a DMD problem, i am a user, my expectation is it should produce a non bloated executable, that's it, as a user i think that's fair to expect that from a compiler that produce native executables And i show you the release build, on debug it is worse, building 10+mbs files constantly, it'll worn the disk, and it makes file transfer painfully slow over the net Again, i am a user, not a compiler personNot a compiler person but a user, too. Since DMD is the reference compiler my expectations are: 1) the code it compiles, any other D compiler will do as well, without requiring modifications to the code 2) the result won't be optimized, neither size nor speed, as well as using e.g. LDC or GDC 3) fast 4) it may not support every platform and/or OS If you're concerned about wearing out your hard drive why don't you build on a RAM drive ? You can add a step to your build config to compress your executable for faster file transfers over the net. If you don't have a build file you can always write a quick make file with a default target and add any flag you want - defining your own defaults - as well as any steps you need to have done pre/post compilation. When you promote D what stops you to mention that DMD is the reference compiler and as such won't produce the best results for deployment and there's LDC and GDC, etc. which about everyone uses for that purpose?
Sep 08 2022
I went ahead and sent a PR: https://github.com/dlang/dmd/pull/14418 Never give up
Sep 05 2022