Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: increased toolchain binary sizes #70699

Closed
cagedmantis opened this issue Dec 5, 2024 · 16 comments
Closed

all: increased toolchain binary sizes #70699

cagedmantis opened this issue Dec 5, 2024 · 16 comments
Labels
binary-size NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@cagedmantis
Copy link
Contributor

Compared to 1.23, binary sizes of most toolchain binaries have increased :

linux amd64          
Files Go1.23 (B) Tip (B) % (+/-)   Go1.23 (M) Tip (M)
go 13387863 19362295 +45   12.76 18.46
gofmt 2850696 4108237 +44   2.71 3.91
addr2line 2814484 4547767 +62   2.68 4.3
asm 4106917 6335065 +54   3.91 6.04
buildid 2271515 3656700 +61   2.16 3.48
cgo 4032102 6009954 +49   3.84 5.73
compile 19798633 28201144 +42   18.88 26.89
covdata 2949306 4191031 +42   2.81 3.99
cover 4567071 6723952 +47   4.35 6.41
dist 2984094 4261242 +43   2.84 4.06
distpack 2397807 3743405 +56   2.28 3.56
doc 3392398 4821225 +42   3.23 4.59
fix 2861911 4154515 +45   2.72 3.96
link 5678421 8691638 +53   5.41 8.28
nm 2776817 4490895 +62   2.64 4.28
objdump 3826204 6053727 +58   3.64 5.77
pack 2030214 2982774 +47   1.93 2.84
pprof 12382808 18451654 +49   11.80 17.59
preprofile 2127222 3140546 +48   2.02 2.99
test2json 2295467 3392933 +48   2.18 3.23
trace 12606079 17061695 +35   12.02 16.27
vet 7194248 10024784 +39   6.86 9.56
@cagedmantis cagedmantis added this to the Go1.24 milestone Dec 5, 2024
@mknyszek mknyszek added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker okay-after-rc1 Used by release team to mark a release-blocker issue as okay to resolve either before or after rc1 labels Dec 5, 2024
@mknyszek
Copy link
Contributor

mknyszek commented Dec 5, 2024

Those seem fairly large. I preemptively marked this as a release blocker, but maybe OK after RC1. Thoughts?

@mknyszek
Copy link
Contributor

mknyszek commented Dec 5, 2024

CC @golang/compiler

@cespare
Copy link
Contributor

cespare commented Dec 5, 2024

Is this something about toolchain binaries in particular? I checked a few binaries in our private codebase (all in the 30-60 MB range) and they only get a bit larger between 1.23 and tip (<2%).

@randall77
Copy link
Contributor

There isn't much more code.
objdump -d on arm64 says there are only 3% more instructions in cmd/go on tip than 1.23.

@randall77
Copy link
Contributor

Looks like dwarf, 1.23.2 binaries have their dwarf stripped, tip binaries do not.

I thought we stripped toolchain binaries. Maybe only for release?

@cherrymui
Copy link
Member

Yeah, we strip toolchain binaries for releases https://cs.opensource.google/go/go/+/master:src/cmd/dist/build.go;l=1393

@cagedmantis
Copy link
Contributor Author

These numbers look much better after using distpack (the proper flags). I will update the numbers and remove the release blocker label.

@timothy-king
Copy link
Contributor

Locally I see the following for gofmt:

% objdump -h /Users/taking/sdk/go1.23.1/bin/gofmt                       

/Users/taking/sdk/go1.23.1/bin/gofmt:   file format mach-o arm64

Sections:
Idx Name            Size     VMA              Type
  0 __text          001209c4 0000000100001000 TEXT
  1 __symbol_stub1  0000030c 00000001001219e0 TEXT
  2 __rodata        00038fee 0000000100121d00 DATA
  3 __rodata        0003e800 000000010015c000 DATA
  4 __typelink      00000c34 000000010019a800 DATA
  5 __itablink      00000548 000000010019b440 DATA
  6 __gosymtab      00000000 000000010019b988 DATA
  7 __gopclntab     000bff10 000000010019b9a0 DATA
  8 __go_buildinfo  00000220 000000010025c000 DATA
  9 __nl_symbol_ptr 00000210 000000010025c220 DATA
 10 __noptrdata     0000b360 000000010025c440 DATA
 11 __data          00006c30 00000001002677a0 DATA
 12 __bss           00026760 000000010026e3e0 BSS
 13 __noptrbss      000035a0 0000000100294b40 BSS
% objdump -h /Users/taking/sdk/gotip/bin/gofmt                             

/Users/taking/sdk/gotip/bin/gofmt:      file format mach-o arm64

Sections:
Idx Name             Size     VMA              Type
  0 __text           0011fd44 0000000100001000 TEXT
  1 __symbol_stub1   00000318 0000000100120d60 TEXT
  2 __rodata         0003ac60 0000000100121080 DATA
  3 __rodata         00042d40 000000010015c000 DATA
  4 __typelink       00000cdc 000000010019ed40 DATA
  5 __itablink       00000550 000000010019fa20 DATA
  6 __gosymtab       00000000 000000010019ff70 DATA
  7 __gopclntab      000c6ca0 000000010019ff80 DATA
  8 __go_buildinfo   00000100 0000000100268000 DATA
  9 __go_fipsinfo    00000078 0000000100268100 DATA
 10 __nl_symbol_ptr  00000218 0000000100268178 DATA
 11 __noptrdata      0000ab82 00000001002683a0 DATA
 12 __data           00006db2 0000000100272f40 DATA
 13 __bss            00026890 0000000100279d00 BSS
 14 __noptrbss       00003580 00000001002a05a0 BSS
 15 __zdebug_abbrev  0000014a 00000001002a4000 DATA, DEBUG
 16 __zdebug_line    00036890 00000001002a414a DATA, DEBUG
 17 __zdebug_frame   0000ba53 00000001002da9da DATA, DEBUG
 18 __debug_gdb_scri 00000034 00000001002e642d DATA, DEBUG
 19 __zdebug_info    0006f772 00000001002e6461 DATA, DEBUG
 20 __zdebug_loc     0003ff6c 0000000100355bd3 DATA, DEBUG
 21 __zdebug_ranges  000130f5 0000000100395b3f DATA, DEBUG

The difference in the binary sizes is 1128962 (locally). The extra sections in the gotip copy of gofmt that are not in 1.23.1 copy add up to 1068084 bytes (95%).

@cagedmantis
Copy link
Contributor Author

The release binaries look much better in terms of the size increase (built with make.bash -distpack):

linux amd64          
files Go1.23 (bytes) Tip (bytes) % (+/-)   MB MB
go 13387863 14271934 7   12.76766109 13.6107769
gofmt 2850696 2922116 3   2.718635559 2.786746979
addr2line 2814484 3365550 20   2.684101105 3.209638596
asm 4106917 4675184 14   3.916661263 4.458602905
buildid 2271515 2591643 14   2.166285515 2.471583366
cgo 4032102 4365513 8   3.845312119 4.163277626
compile 19798633 20899679 6   18.88144779 19.93148708
covdata 2949306 2999246 2   2.812677383 2.860303879
cover 4567071 4947863 8   4.355498314 4.718649864
dist 2984094 3051249 2   2.845853806 2.909897804
distpack 2397807 2663964 11   2.286726952 2.540554047
doc 3392398 3453200 2   3.235242844 3.293228149
fix 2861911 2959114 3   2.729331017 2.822031021
link 5678421 6242053 10   5.415364265 5.952885628
nm 2776817 3332582 20   2.648179054 3.178197861
objdump 3826204 4621606 21   3.648952484 4.407506943
pack 2030214 2092973 3   1.936162949 1.996014595
pprof 12382808 13910725 12   11.80916595 13.26630116
preprofile 2127222 2208161 4   2.028676987 2.105866432
test2json 2295467 2393740 4   2.189127922 2.282848358
trace 12606079 13407966 6   12.02209377 12.78683281
vet 7194248 7469567 4   6.860969543 7.123534203

@cherrymui
Copy link
Member

Thanks @cagedmantis .

objdump's increase is somewhat reasonable, as we added more disassembler support (e.g. s390x disassembler). pprof supports disassembling, so it is probably also reasonable.

The disassembler symbols (golang.org/x/arch stuff) also show up in nm and addr2line, causing them to increase as well. In theory I don't think they need disassembler symbols, so this is unfortunate. I'll see if we can remove those symbols from nm and addr2line.

@andig
Copy link
Contributor

andig commented Dec 8, 2024

fwiw, I've found that evcc Linux binary slightly shrinks from 1.23 to tip: 91485682 vs 90495826 bytes.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/634916 mentions this issue: cmd/internal/objfile: break out dissassemblers to another package

@cherrymui
Copy link
Member

cherrymui commented Dec 10, 2024

After nm, addr2line, objdump, and pprof, the next ones are asm and buildid.

One part that they depend on now but not in Go 1.23 is crypto FIPS stuff, as they perform various crypto hash operations. In 1.23 most of the hash operations use notsha256, which is deleted in CL 610599 and switched to real sha256, which now depends on FIPS things. We get some binary size back if we revert back to notsha256. Not completely, though.

Another place for at least cmd/asm is that they now contain a number of different instantiations of slices.Sort routines. The old code was using sort.Sort or sort.Slice, which is not generic. I guess this increase is okay...

gopherbot pushed a commit that referenced this issue Dec 11, 2024
Currently, cmd/internal/objfile provides dissassembly routines for
various architectures, which depend on dissassemblers from x/arch.
cmd/internal/objfile is imported in tools that need dissassembly
(objdump, pprof) and tools that don't need dissassembly (nm,
addr2line). Adding/improving disassembly support for more
architectures can cause binary size increase, and for some tools
(nm, addr2line) it is not necessary.

This CL breaks out dissassembly routines to a different package,
which is only imported in tools that need dissassembly. Other
tools can depend on cmd/internal/objfile without the disassembly
code from x/arch.

This reduces binary sizes for those tools. On darwin/arm64,

                                 old         new
cmd/addr2line                  4554418     3648882   -20%
cmd/addr2line (-ldflags=-w)    3464626     2641650   -24%
cmd/nm                         4503874     3616722   -20%
cmd/nm (-ldflags=-w)           3430594     2609490   -24%

For #70699.

Change-Id: Ie45d5d5c5500c5f3882e8b3c4e6eb81f0d815292
Reviewed-on: https://go-review.googlesource.com/c/go/+/634916
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
@gopherbot gopherbot removed the okay-after-rc1 Used by release team to mark a release-blocker issue as okay to resolve either before or after rc1 label Dec 13, 2024
@Zxilly
Copy link
Member

Zxilly commented Dec 19, 2024

The tool I wrote includes a diff go binary feature that might come in handy.

https://github.com/Zxilly/go-size-analyzer?tab=readme-ov-file#diff-mode

@cherrymui
Copy link
Member

cherrymui commented Dec 19, 2024

I did another run with GOOS=linux GOARCH=amd64 make.bash -distpack

                  go1.23.3             tip           delta      %delta
          go	  13397287	  14280843	    883556	6.60
       gofmt	   2855408	   2922116	     66708	2.34
   addr2line	   2819123	   2627110	   -192013	-6.81
         asm	   4115652	   4675046	    559394	13.59
     buildid	   2280250	   2591505	    311255	13.65
         cgo	   4040817	   4365375	    324558	8.03
     compile	  19803234	  20934109	   1130875	5.71
     covdata	   2953945	   2999246	     45301	1.53
       cover	   4575841	   4943679	    367838	8.04
         doc	   3401113	   3453200	     52087	1.53
         fix	   2866530	   2959114	     92584	3.23
        link	   5683028	   6246132	    563104	9.91
          nm	   2781456	   2608126	   -173330	-6.23
     objdump	   3830843	   4621684	    790841	20.64
        pack	   2030757	   2092973	     62216	3.06
       pprof	  12387591	  13915107	   1527516	12.33
  preprofile	   2127765	   2208161	     80396	3.78
   test2json	   2300013	   2393740	     93727	4.08
       trace	  12610862	  13412106	    801244	6.35
         vet	   7194840	   7469230	    274390	3.81
----------------------------------------------------------------------
       total	 114056355	 121718602	   7662247	6.72

The changes we inspected are all more or less expected (supporting more features, reasonable refactoring, etc.). I don't think we need to do anything more on this at the moment. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
binary-size NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

10 participants