[HN Gopher] Huge Binaries
       ___________________________________________________________________
        
       Huge Binaries
        
       Author : todsacerdoti
       Score  : 185 points
       Date   : 2025-12-29 05:35 UTC (17 hours ago)
        
 (HTM) web link (fzakaria.com)
 (TXT) w3m dump (fzakaria.com)
        
       | gerikson wrote:
       | The HN de-sensationalize algo for submission titles needs
       | tweaking. Original title is simply "Huge Binaries".
        
         | acosmism wrote:
         | agreed. Binaries is a bit too sensational for my taste. this
         | can be further optimized.
        
           | binaryturtle wrote:
           | "Bins"? :)
        
             | bayindirh wrote:
             | 01.
             | 
             | Why not?
        
               | DHRicoF wrote:
               | False
        
           | fuzzfactor wrote:
           | "Files So Big They Might As Well Be Trinaries".
        
       | doubletwoyou wrote:
       | 25 GiB for a single binary sounds horrifying
       | 
       | at some point surely some dynamic linking is warranted
        
         | nneonneo wrote:
         | To be fair, this is with debug symbols. Debug builds of Chrome
         | were in the 5GB range several years ago; no doubt that's
         | increased since then. I can remember my poor laptop literally
         | running out of RAM during the linking phase due to the sheer
         | size of the object files being linked.
         | 
         | Why are debug symbols so big? For C++, they'll include detailed
         | type information for every instantiation of every type
         | everywhere in your program, including the types of every field
         | (recursively), method signatures, etc. etc., along with the
         | types and locations of local variables in every method (updated
         | on every spill and move), line number data, etc. etc. for every
         | specialization of every function. This produces a lot of data
         | even for "moderate"-sized projects.
         | 
         | Worse: for C++, you don't win much through dynamic linking
         | because dynamically linking C++ libraries sucks so hard.
         | Templates defined in header files can't easily be put in shared
         | libraries; ABI variations mean that dynamic libraries generally
         | have to be updated in sync; and duplication across modules is
         | bound to happen (thanks to inlined functions and templates). A
         | single "stuck" or outdated .so might completely break a
         | deployment too, which is a much worse situation than deploying
         | a single binary (either you get a new version or an old one,
         | not a broken service).
        
           | tempay wrote:
           | I've seen LLVM dependent builds hit well over 30GB. At that
           | point it started breaking several package managers.
        
           | 01HNNWZ0MV43FF wrote:
           | I've hit the same thing in Rust, probably for the same
           | reasons.
           | 
           | Isn't the simple solution to use detached debug files?
           | 
           | I think Windows and Linux both support them. That's how
           | phones like Android and iOS get useful crash reports out of
           | small binaries, they just upload the stack trace and some
           | service like Sentry translates that back into source line
           | numbers. (It's easy to do manually too)
           | 
           | I'm surprised the author didn't mention it first. A 25 GB exe
           | might be 1 GB of code and 24 GB of debug crud.
        
             | dwattttt wrote:
             | > I think Windows and Linux both support them.
             | 
             | Detached debug files has been the default (only?) option in
             | MS's compiler since at least the 90s.
             | 
             | I'm not sure at what point it became hip to do that around
             | Linux.
        
               | kvemkon wrote:
               | Since at least October 2003 on Debian:
               | 
               | [1] "debhelper: support for split debugging symbols"
               | 
               | https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=215670
               | 
               | [2] https://salsa.debian.org/debian/debhelper/-/commit/79
               | 411de84...
        
             | nicoburns wrote:
             | > Isn't the simple solution to use detached debug files?
             | 
             | It should be. But the tooling for this kind of thing
             | (anything to do with executable formats including debug
             | info and also things like linking and cross-compilation) is
             | generally pretty bad.
        
           | yjftsjthsd-h wrote:
           | Can't debug symbols be shipped as separate files?
        
             | yablak wrote:
             | Yes, but it can be more of a pain keeping track of pairs.
             | In production though, this is what's done. And given a
             | fault, the debug binary can be found in a database and used
             | to gdb the issue given the core. You do have to limit
             | certain online optimizations in order to have useful
             | tracebacks.
             | 
             | This also requires careful tracking of prod builds and
             | their symbol files... A kind of symbol db.
        
             | bregma wrote:
             | The problem is that when a final binary is linked
             | everything goes into it. Then, after the link step, all the
             | debug information gets stripped out into the separate
             | symbols file. That means at some point during the build the
             | target binary file will contain everything. I can not, for
             | example, build clang in debug mode on my work machine
             | because I have only 32 GB of memory and the OOM killer
             | comes out during the final link phase.
             | 
             | Of course, separate binaries files make no difference at
             | runtime since only the LOAD segments get loaded (by either
             | the kernel or the dynamic loader, depending). The size of a
             | binary on disk has little to do with the size of a binary
             | in memory.
        
               | jcelerier wrote:
               | > The problem is that when a final binary is linked
               | everything goes into it
               | 
               | I don't think that's the case on Linux, when using
               | -gsplit-dwarf the debug info is put in separate files at
               | the object file level, they are never linked into
               | binaries.
        
             | loeg wrote:
             | Yes, absolutely. Debuginfo doesn't impact .text section
             | distances either way, though.
        
         | 0xbadcafebee wrote:
         | To be fair, they worked at Google, their engineering decisions
         | are not normal. They might just decide that 25 GiB binaries are
         | worth a 0.25% speedup at start time, potentially resulting in
         | tens of millions of dollars' worth of difference. Nobody should
         | do things the way Google does, but it's interesting to think
         | about.
        
         | flohofwoe wrote:
         | The overall size wouldn't get smaller just because it is
         | dynamically linked, on the contrary (because DLLs are a dead
         | code elimination barrier). 25 GB is insane either way,
         | something must have gone horribly wrong very early in the
         | development process (also why, even ship with debug information
         | included, that doesn't make sense in the first place).
        
         | dilyevsky wrote:
         | Won't make a bit of difference because everything is in a sort
         | of container (not Docker) anyway. Unless you're suggesting
         | those libraries to be distributed as base image to every
         | possible Borg machine your app can run on which is an obvious
         | non-starter.
        
       | yjftsjthsd-h wrote:
       | > I had observed binaries beyond 25GiB, including debug symbols.
       | How is this possible? These companies prefer to statically build
       | their services to speed up startup and simplify deployment.
       | Statically including all code in some of the world's largest
       | codebases is a recipe for massive binaries.
       | 
       | I am _very_ sympathetic to wanting nice static binaries that can
       | be shipped around as a single artifact[0], but... surely at some
       | point we have to ask if it 's worth it? If nothing else, that
       | feels like a little bit of a code smell; surely if your actual
       | executable code doesn't even fit in 2GB it's time to ask if
       | that's _really_ one binary 's worth of code or if you're actually
       | staring at like... a dozen applications that deserve to be
       | separate? Or get over it the other way and accept that sometimes
       | the single artifact you ship is a tarball / OCI image / EROFS
       | image for systemd[1] to mount+run / self-extracting archive[2] /
       | ...
       | 
       | [0] Seriously, one of my background projects right now is trying
       | to figure out if it's really _that_ hard to make fat ELF
       | binaries.
       | 
       | [1] https://systemd.io/PORTABLE_SERVICES/
       | 
       | [2] https://justine.lol/ape.html > "PKZIP Executables Make Pretty
       | Good Containers"
        
         | jmmv wrote:
         | This is something that always bothered me while I was working
         | at Google too: we had an amazing compute and storage
         | infrastructure that kept getting crazier and crazier over the
         | years (in terms of performance, scalability and redundancy) but
         | everything in operations felt slow because of the massive size
         | of binaries. Running a command line binary? Slow. Building a
         | binary for deployment? Slow. Deploying a binary? Slow.
         | 
         | The answer to an ever-increasing size of binaries was always
         | "let's make the infrastructure scale up!" instead of "let's...
         | not do this crazy thing maybe?". By the time I left, there were
         | some new initiatives towards the latter and the feeling that
         | "maybe we should have put limits much earlier" but retrofitting
         | limits into the existing bloat was going to be exceedingly
         | difficult.
        
           | joatmon-snoo wrote:
           | There's a lot of tooling built on static binaries:
           | 
           | - google-wide profiling: the core C++ team can collect data
           | on how much of fleet CPU % is spent in absl::flat_hash_map
           | re-bucketing (you can find papers on this publicly)
           | 
           | - crashdump telemetry
           | 
           | - dapper stack trace -> codesearch
           | 
           | Borg literally had to pin the bash version because letting
           | the bash version float caused bugs. I can't imagine how much
           | harder debugging L7 proxy issues would be if I had to follow
           | a .so rabbit hole.
           | 
           | I can believe shrinking binary size would solve a lot of
           | problems, and I can imagine ways to solve the .so versioning
           | problem, but for every problem you mention I can name
           | multiple other probable causes (eg was startup time really
           | execvp time, or was it networked deps like FFs).
        
             | Filligree wrote:
             | There's no way my proxy binary actually requires 25GB of
             | code, or even the 3GB it is. Sounds to me like the answer
             | is a tree shaker.
        
               | Sesse__ wrote:
               | Google implemented the C++ equivalent of a tree shaker in
               | their build system around 2009.
        
               | setheron wrote:
               | the front-end services to be "fast" AFAIK probably
               | include nearly all the services you need to avoid hops --
               | so you can't really shake that much away.
        
           | lenkite wrote:
           | Maybe I am missing something, but why didn't they just
           | leverage dynamic libraries ?
        
             | tmoertel wrote:
             | One reason is that using static binaries greatly simplifies
             | the problem of establishing Binary Provenance, upon which
             | security claims and many other important things rely. In
             | environments like Google's it's important to know that what
             | you have deployed to production is _exactly_ what you think
             | it is.
             | 
             | See for more: https://google.github.io/building-secure-and-
             | reliable-system...
        
             | btilly wrote:
             | When I was at Google, on an SRE team, here is the
             | explanation that I was given.
             | 
             | Early on Google used dynamic libraries. But weird things
             | happen at Google scale. For example Google has a dataset
             | known, for fairly obvious reasons, as "the web". Basically
             | any interesting computation with it takes years. Enough to
             | be a multiple of the expected lifespan of a random
             | computer. Therefore during that computation, you have to
             | expect every random thing that tends to go wrong, to go
             | wrong. Up to and including machines dying.
             | 
             | One of the weird things that becomes common at Google
             | scale, are cosmic bit flips. With static binaries, you can
             | figure out that something went wrong, kill the instance,
             | launch a new one, and you're fine. That machine will later
             | launch something else and also be fine.
             | 
             | But what happens if there was a cosmic bit flip in a
             | dynamic library? Everything launched on that machine will
             | be wrong. This has to get detected, then the processes
             | killed and relaunched. Since this keeps happening, that
             | machine is always there lightly loaded, ready for new stuff
             | to launch. New stuff that...wind up broken for the same
             | reason! Often the killed process will relaunch on the bad
             | machine, failing again! This will continue until someone
             | reboots the machine.
             | 
             | Static binaries are wasteful. But they aren't as
             | problematic for the infrastructure as detecting and fixing
             | this particular condition. And, according to SRE lore circa
             | 2010, this was the actual reason for the switch to static
             | binaries. And then they realized all sorts of other
             | benefits. Like having a good upgrade path for what would
             | normally be shared libraries.
        
               | dh2022 wrote:
               | In Azure - which I think is at Google scale - everything
               | is dynamically linked. Actually a lot of Azure is built
               | on C# which does not even support static linking...
               | 
               | Statically linking being necessary for scaling does not
               | pass the smell test for me.
        
               | arccy wrote:
               | perhaps that's why azure has such a bad reputation in the
               | devops crowd.
        
               | dh2022 wrote:
               | Does AWS have a good reputation in devops? Because large
               | chunks of AWS are built on Java - which also does not
               | offer static linking (bundling a bunch of *.jar files
               | into one exe does not count as static linking). Still
               | does not pass the smell test.
        
               | arccy wrote:
               | In AWS, only the very core Infra-as-a-Service that they
               | dogfood can be considered "good", Everything else that's
               | more Platform-as-a-Service can be considered a half baked
               | leaky abstraction. Anything they release as "GA"
               | especially around ReInvent should be avoided for a
               | minimum of 6 months-1 year since it's more like a public
               | Beta with some guaranteed bugs.
        
               | mbreese wrote:
               | I never worked for Google, but have seen some strange
               | things like bit flips at more modest scales. From the
               | parent description, it looks like defaulting to static
               | binaries is helping to speed up troubleshooting to remove
               | the "this should never happen, but statistically will
               | happen every so often" class of bugs.
               | 
               | As I see it, the issue isn't requiring static compiling
               | to scale. It's requiring it to make troubleshooting or
               | measuring performance at scale easier. Not required, per
               | se, but very helpful.
        
               | btilly wrote:
               | Exactly. SRE is about monitoring and troubleshooting at
               | scale.
               | 
               | Google runs on a microservices architecture. It's done
               | that since before that was cool. You have to do a lot to
               | make a microservices architecture work. Google did not
               | advertise a lot of that. Today we have things like Data
               | Dog that give you some of the basics. But for a long
               | time, people who left Google faced a world of pain
               | because of how far behind the rest of the world was.
        
               | btilly wrote:
               | Azure's devops record is not nearly as good as Google's
               | was.
               | 
               | The biggest datasets that ChatGPT is aware of being
               | processed in complex analytics jobs on Azure are roughly
               | a thousand times smaller than an estimate of Google's
               | regularly processed snapshot of the web. There is a
               | reason why most of the fundamental advancements in how to
               | parallelize data and computations - such as map-reduce
               | and BigTable - all came from Google. Nobody else worked
               | at their scale before they did. (Then Google published
               | it, and people began to implement it. Then failed to
               | understand what was operationally important to making it
               | actually work at scale...)
               | 
               | So, despite how big it is, I don't think that Azure
               | operates at Google scale.
               | 
               | For the record, back when I worked at Google, the public
               | internet was only the third largest network that I knew
               | of. Larger still was the network that Google uses for
               | internal API calls. (Do you have any idea how many API
               | calls it takes to serve a Google search page?) And larger
               | still was the network that kept data synchronized between
               | data centers. (So, for example, you don't lose your mail
               | if a data center goes down.)
        
               | ambrosio wrote:
               | > But what happens if there was a cosmic bit flip in a
               | dynamic library?
               | 
               | I think there were more basic reasons we didn't ship
               | shared libraries to production.
               | 
               | 1. They wouldn't have been "shared", because every
               | program was built from its own snapshot of the monorepo,
               | and would naturally have slightly different library
               | versions. Nobody worried about ABI compatibility when
               | evolving C++ interfaces, so (in general) it wasn't
               | possible to reuse a .so built at another time. Thus, it
               | wouldn't actually save any disk space or memory to use
               | dynamic linking.
               | 
               | 2. When I arrived in 2005, the build system was embedding
               | absolute paths to shared libraries into the final
               | executable. So it wasn't possible to take a dynamically
               | linked program, copy it to a different machine, and
               | execute it there, unless you used a chroot or container.
               | (And at that time we didn't even use mount namespaces on
               | prod machines.) This was one of the things we had to fix
               | to make it possible to run tests on Forge.
               | 
               | 3. We did use shared libraries for tests, and this
               | revealed that ld.so's algorithm for symbol resolution was
               | quadratic in the number of shared objects. Andrew Chatham
               | fixed some of this (https://sourceware.org/legacy-
               | ml/libc-alpha/2006-01/msg00018...), and I got the rest of
               | it eventually; but there was a time before GRTE, when we
               | didn't have a straightforward way to patch the glibc in
               | prod.
               | 
               | That said, I did hear a similar story from an SRE about
               | fear of bitflips being the reason they wouldn't put the
               | gws command line into a flagfile. So I can imagine it
               | being a rationale for not even trying to fix the above
               | problems in order to enable dynamic linking.
               | 
               | > Since this keeps happening, that machine is always
               | there lightly loaded, ready for new stuff to launch. New
               | stuff that...wind up broken for the same reason!
               | 
               | I did see this failure mode occur for similar reasons,
               | such as corruption of the symlinks in /lib. (google3
               | executables were typically not totally static, but still
               | linked libc itself dynamically.) But it always seemed to
               | me that we had way more problems attributable to kernel,
               | firmware, and CPU bugs than to SEUs.
        
               | btilly wrote:
               | Thanks. It is nice to hear another perspective on this.
               | 
               | But here is a question. How much of SEUs not being
               | problems were because they weren't problems? Versus
               | because there were solutions in place to mitigate the
               | potential severity of that kind of problem? (The other
               | problems that you name are harder to mitigate.)
        
           | darubedarob wrote:
           | I think google of all companies could build a good
           | autostripper reducing binaries by adding partial load
           | assembly on misses. It cant be much slower then shovelling a
           | full monorepo assembly plus symbols into ram.
        
             | loeg wrote:
             | The low-hanging fruit is just not shipping the debuginfo,
             | of course.
        
               | usefulcat wrote:
               | Is compressed debug info a thing? It seems likely to
               | compress well, and if it's rarely used then it might be a
               | worthwhile thing to do?
        
               | loeg wrote:
               | It is: https://maskray.me/blog/2022-01-23-compressed-
               | debug-sections
               | 
               | But the compression ratio isn't magical (approx. 1:0.25,
               | for both zlib and zstd in the examples given). You'd
               | probably still want to set aside debuginfo in separate
               | files.
        
           | bfrog wrote:
           | Sounds like Google could really use Nix
        
         | forrestthewoods wrote:
         | If you have 25gb of executables then I don't think it matters
         | if that's one binary executable or a hundred. Something has
         | gone horribly horribly wrong.
         | 
         | I don't think I've ever seen a 4gb binary yet. I have seen
         | instances where a PDB file hit 4gb and _that_ caused problems.
         | Debug symbols getting that large is totally plausible. I'm ok
         | with that at least.
        
           | wolfi1 wrote:
           | I did, it was a Spring Boot fat jar with a NLP, I had to
           | deploy it to the biggest instance AWS could offer, the costs
           | were enormous
        
           | throwawaymobule wrote:
           | A few ps3 games I've seen had 4GB or more binaries.
           | 
           | This was a problem because code signing meant it needed to be
           | completely replaced by updates.
        
             | swiftcoder wrote:
             | > A few ps3 games I've seen had 4GB or more binaries.
             | 
             | Is this because they are embedding assets into the binary?
             | I find it hard to believe anyone was carrying around enough
             | code to fill 4GB in the PS3 era...
        
               | throwawaymobule wrote:
               | I assume so, there were rarely any other files on the
               | disc in this case.
               | 
               | It varied between games, one of the battlefields (3 or
               | bad company 2) was what I was thinking of. It generally
               | improved with later releases.
               | 
               | The 4GB file size was significant, since it meant I
               | couldn't run them from a backup on a fat32 usb drive.
               | There are workarounds for many games nowadays.
        
           | loeg wrote:
           | If you haven't seen a 25GB binary with debuginfo, you just
           | aren't working in large, templated, C++ codebases. It's
           | nothing special there.
        
             | forrestthewoods wrote:
             | Not quite. I very much work in large, templated, C++
             | codebases. But I do so on windows where the symbols are in
             | a separate file the way the lord intended.
        
           | niutech wrote:
           | Llamafile (https://llamafile.ai) can easily exceed 4GB due to
           | containing LLM weights inside. But remember, you cannot run
           | >4GB executable files on Windows.
        
         | shevy-java wrote:
         | > https://systemd.io/PORTABLE_SERVICES/
         | 
         | Systemd and portable?
        
           | yjftsjthsd-h wrote:
           | Portable across systemd/Linux systems, yes:)
        
         | jcelerier wrote:
         | What's wild to me is not using -gsplit-dwarf to have separate
         | debug info and "normal-sized" binaries
        
           | jeffbee wrote:
           | Google contributed the code, and the entire concept, of DWARF
           | fission to both GCC and LLVM. This suggests that rather than
           | overlooking something obvious that they'll be embarrassed to
           | learn on HN, they were aware of the issues and were using the
           | solutions before you'd even heard of them.
        
             | sionisrecur wrote:
             | A case of the left hand not knowing what the right hand is
             | doing?
        
               | jeffbee wrote:
               | There's no contradiction, no missing link in the facts of
               | the story. They have a huge program, it is 2GiB minus
               | epsilon of .text, and a much larger amount of DWARF
               | stuff. The article is about how to use different code
               | models to potentially go beyond 2GiB of text, and the
               | size of the DWARF sections is irrelevant trivia.
        
               | jcelerier wrote:
               | > They have a huge program, it is 2GiB minus epsilon of
               | .text,
               | 
               | but the article says 25+GiB _including debug symbols_ ,
               | in a single binary?
               | 
               | also, I appreciate your enthusiasm in assuming that
               | because some people do something in an organization, it
               | is applied consistently everywhere. Hell, if it were
               | microsoft other departments would try to shoot down the
               | "debug tooling optimization" dpt
        
               | jeffbee wrote:
               | ELF is just a container format and you can put literally
               | anything into one of its sections. Whether the DWARF
               | sections are in "the binary" or in another named file is
               | really quite beside the point.
        
               | loeg wrote:
               | Yes, the 25GB figure in the article is basically
               | irrelevant to the 2GB .text section concern. Most ELF
               | files that size are 95%+ debuginfo.
        
       | a_t48 wrote:
       | I've seen terrible, terrible binary sizes with Eigen + debug
       | symbols, due to how Eigen lazy evaluation works (I think). Every
       | math expression ends up as a new template instantiation.
        
         | forrestthewoods wrote:
         | Eigen is one of the worst libraries when it comes to both exe
         | size and compile times. <shudder>
        
           | a_t48 wrote:
           | In terms of compile times, boost geometry is somehow worse.
           | You're encouraged to import boost/geometry.hpp, which
           | includes every module, which stalls compile times by several
           | seconds just to parse all the templates. It's not terrible if
           | you include just the headers you need, but that's not the
           | "default" that most people use.
        
             | forrestthewoods wrote:
             | boost is on my "do not ever use ever oh my god what are you
             | doing stop it" list. It's so bad.
        
               | a_t48 wrote:
               | Same.
        
       | stncls wrote:
       | > The simplest solution however is to use -mcmodel=large which
       | changes all the relative CALL instructions to absolute JMP.
       | 
       | Makes sense, but in the assembly output just after, there is not
       | a single JMP instruction. Instead, CALL <immediate> is replaced
       | with putting the address in a 64-bit register, then CALL
       | <register>, which makes even more sense. But why mention the JMP
       | thing then? Is it a mistake or am I missing something? (I know
       | some calls are replaced by JMP, but that's done regardless of
       | -mcmodel=large)
        
         | dwattttt wrote:
         | I would assume loose language, referring to a CALL as a JMP.
         | However of the two reasons given to dislike the large code
         | model, register pressure isn't relevant to that particular
         | snippet.
         | 
         | It's performing a call, ABIs define registers that are not
         | preserved over calls; writing the destination to one of those
         | won't affect register pressure.
        
         | loeg wrote:
         | I think the author is just noting that the construction is
         | similar to an 8-byte JMP instruction. The text now reads:
         | 
         | > The simplest solution however is to use -mcmodel=large which
         | changes all the relative CALL instructions to _absolute 64bit
         | ones; kind of like a JMP_.
         | 
         | (We still need to use CALL in order to push a return address.)
        
       | 10000truths wrote:
       | Debug symbol size shouldn't be influencing relocation jump
       | distances - debug info has its own ELF section.
       | 
       | Regardless of whether you're FAANG or not, nothing you're running
       | should require an executable with a 2 GB large .text section. If
       | you're bumping into that limit, then your build process likely
       | lacks dead code elimination in the linking step. You should be
       | using LTO for release builds. Even the traditional solution
       | (compile your object files with -ffunction-sections and link with
       | --gc-sections) does a good job of culling dead code at function-
       | level granularity.
        
         | yablak wrote:
         | FAANGs we're deeply involved in designing LTO. See, e.g.,
         | 
         | https://research.google/pubs/thinlto-scalable-and-incrementa...
         | 
         | And other refs.
         | 
         | And yet...
        
           | jeffbee wrote:
           | Google also uses identical code folding. It's a pretty silly
           | idea that a shop that big doesn't know about the compiler
           | flags.
        
             | Orphis wrote:
             | Google is made of many thousands of individuals. Some
             | experts will be aware of all those, some won't. In my team,
             | many didn't know about those details as they were handled
             | by other builds teams for specific products or entire
             | domains at once.
             | 
             | But since each product in some different domains had to
             | actively enable those optimizations for themselves, they
             | were occasionally forgotten, and I found a few in the app I
             | worked for (but not directly on).
        
               | jeffbee wrote:
               | ICF seems like a good one to keep in the box of flags
               | people don't know about because like everything in life
               | it's a tradeoff and keeping that one problematic artifact
               | under 2GiB is pretty much the only non-debatable use case
               | for it.
        
         | saagarjha wrote:
         | Google Chrome ships as a 500 MB binary on my machine, so if
         | you're embedding a web browser, that's how much you need
         | minimum. Now tack on whatever else your application needs and
         | it's easy to see how you can go past 2 GB if you're not
         | careful. (To be clear, I am not making a moral judgment here, I
         | am just saying it's possible to do. Whether it _should_ happen
         | is a different question.)
        
           | throwawaymobule wrote:
           | Do you have some special setup?
           | 
           | Chromium is in the hundred and something MB range on mine
           | last I looked. Might expand to more on install.
        
             | saagarjha wrote:
             | I just checked Google Chrome Framework on my Mac, it was a
             | little over 400 MB. Although now that I think about it it's
             | probably a universal binary so you can cut that in half?
        
               | trevor-e wrote:
               | Yea looks like Chrome ships a universal binary with both
               | x86_64 and arm64.
        
               | sznio wrote:
               | makes sense, chromium on my Fedora system takes up 234MB.
        
       | yablak wrote:
       | > We would like to keep our small code-model. What other
       | strategies can we pursue?
       | 
       | Move all the hot BBs near each other, right?
       | 
       | Facebook's solution: https://github.com/llvm/llvm-
       | project/blob/main/bolt%2FREADME...
       | 
       | Google's:
       | 
       | https://lists.llvm.org/pipermail/llvm-dev/2019-September/135...
        
         | setheron wrote:
         | but for x86_64, as of right now, if only a single call needs
         | more than 31bits you have to upgrade the whole code section to
         | large code model.
         | 
         | BOLT AFAIU is more about cache locality of putting hot code
         | near each other and not really breaking the 2GiB barrier.
        
           | jeffbee wrote:
           | Why? Can't the linker or post-link optimizer reduce all near
           | calls, leaving the more complicated mov with immediate form
           | only where required?
        
       | shevy-java wrote:
       | 25GB seems excessive, but I keep on having the basic compile
       | toolchain as statically compiled executables. It simply works
       | better when things go awry.
        
       | wyldfire wrote:
       | > What other strategies can we pursue?
       | 
       | You can use thunks/trampolines. lld can make them for some
       | architectures, presumably also for x86_64. Though I don't know
       | why it didn't in your case.
       | 
       | But, like the large code model it can be expensive to add
       | trampolines, both in icache performance and just execution if a
       | trampoline is in a particularly hot path.
        
         | setheron wrote:
         | In many ways that is what the PLT is also.
         | 
         | This is what my next post will explore. I ran into some issues
         | with the GOT that I'll have to explore solutions for.
         | 
         | I'm writing this for myself mostly. The whole idea for code
         | models when you have thunks feels unnecessary.
        
         | setheron wrote:
         | follow-up: https://fzakaria.com/2025/12/29/huge-binaries-i-
         | thunk-theref...
        
           | wyldfire wrote:
           | > With this information, the necessity of code-models feels
           | unecessary [sic]. Why trigger the cost for every callsite
           | when we can do-so piecemeal as necessary with the opportunity
           | to use profiles to guide us on which methods to migrate to
           | thunks.
           | 
           | Does the linker have access to the same hotness information
           | that the compiler uses during PGO? Well -- presumably it
           | _could_ , even if it doesn't now. But it would be like a
           | heuristic with a hotness threshold? Do linkers "do"
           | heuristics?
        
       | meisel wrote:
       | > Responses to my publication submissions often claimed such
       | problems did not exist
       | 
       | I see this often even in communities of software engineers, where
       | people who are unaware of certain limitations at scale will
       | announce that the research is unnecessary
        
       | loeg wrote:
       | Sure! But there's a sleight of hand in the numbers here where
       | we're talking about 25GB binaries _with debuginfo_ and then 2GB
       | maximum offsets _in the .text section_. Of those 25GB binaries,
       | probably 24.5 of them are debuginfo. You have to get into truly
       | huge binaries before  >2GB calls become an issue.
       | 
       | (I wonder but have no particular insight into if LTO builds can
       | do smarter things here -- most calls are local, but the handful
       | of far calls can use the more expensive spelling.)
        
         | benlivengood wrote:
         | At Google I worked with one statistics aggregation binary[0]
         | that was ~25GB stripped. The distributed build system wouldn't
         | even build the debug version because it exceeded the maximum
         | configured size for any object file. I never asked if anyone
         | had tried factoring it into separate pipelines but my intuition
         | is that the extra processing overhead wouldn't have been worth
         | splitting the business logic that way; once the exact set of
         | necessary input logs are in memory you might as well do
         | everything you need to them given the dramatically larger ratio
         | of data size to code size.
         | 
         | [0] https://research.google/pubs/ubiq-a-scalable-and-fault-
         | toler...
        
       | reactordev wrote:
       | Oh man, that first paragraph. "Such problems don't exist..." what
       | a gaslighting response to a publication submittal. The least they
       | could do is ask where this problem emerges and you can hand wavy
       | your answer without revealing business IP.
       | 
       | Also, we, as an industry of software engineers, need to re-
       | examine these hard defaults we thought could never be achieved.
       | Such as the _.text_ limits.
       | 
       | Anyway, very good read.
        
       | nicebyte wrote:
       | shameless plug: if you want to understand the content of this
       | post better, first read the first half of my article on jumps [1]
       | (up to syscall). goes into detail about relocations and position-
       | independent code.
       | 
       | [1] https://gpfault.net/posts/asm-tut-4.html
        
       ___________________________________________________________________
       (page generated 2025-12-29 23:01 UTC)