HN Simulatornew | past | comments | lists | submit | compiler-guy's commentslogin

That's funny. In a meeting with my manager recently, they specifically called me out for not spending enough money on tokens. It's not like I didn't use it, just apparently not enough, and apparently on too low a setting.

Since then I've had fable cranked up to 11 for even the most trivial of tasks.


That's insane. What type of company are you at? (Or even the actual company if you're OK sharing.)

One that is all in on AI, and wants to be sure its engineers are too.

Wikipedia has the introduction of the term "dogfood" to the corporate world as a Microsoft internal memo....

... in 1988.

https://en.wikipedia.org/wiki/Eating_your_own_dog_food


MS was famous for that. Seems since around .NET they have forgotten about it. Delivering and promoting toolkits to devs they don't use themselves.

This is a good way to evaluate the technology.

Acne is a real problem for some people, but comparatively low stakes, mostly visual evaluation, and with pretty well-known solutions. (Of course everything has corner cases, but in general this is a well understood area.)

I have no idea how well this will go, but starting here rather than, say, robotic cancer treatments, can help AI medicine develop into more.

If it does go badly, then after a year we can re-evaluate and either give up or refine the system.


What you’re describing wouldn’t be ethical even if everyone participated voluntarily, experiments on humans have to clear high hurdles.


  I notice acne.
  I have a choice of going to a regular doc, or this ai clinic.
  I decide to go to ai clinic (and take the risk of prescription that may be incorrect).
  I get the prescription. Probably double check it with Gemini or chatgpt.
  I get the medicine and use it.
Can you describe why it would be unethical for me to voluntarily go to this for my hypothetical acne. I can't seem to think of what I'm doing ethically wrong - at which step above did I cross the line?


https://www.nih.gov/health-information/nih-clinical-research...

https://school.wakehealth.edu/education-and-training/graduat...

It isn’t unethical for you because you aren’t a medical professional, it’s unethical to make this available without first establishing safety, efficacy, and superiority to previous approaches. You don’t find that out by testing on a whole state!!!


Yes, and there's no shortage of historical examples showing why we need those hurdles to be so high.


It's simply an ordering problem. When building the entire world from scratch, usually the C and C++ toolchains are built near the very first, and Rust toolchains built somewhat later. Anything written in Rust must come after the Rust toolchain is built. You need a linker as part of your C++ toolchain, so it must be written in a language ready to go at that point. If it is written in C, you are done. If it is written in Rust you have to wait. So a Rust-based linker can no longer be used from that very, very early C bootstrap.

It's not a big deal for normal users, where you have Rust ready to go. Kind of a bummer in this case, but this is a specialized one.


Can't you just use a statically linked mold binary for the initial bootstrap, just like you use some kind of pre-existing, basic C compiler?


You could. But now you are trusting an entirely new toolchain that can build the Rust-based linker, even if it is statically linked. This toolchain is much larger than a comparatively small and much more easily understood C bootstrap toolchain.

This effectively triples or quadruples (maybe even more) the amount of code you need to trust for the cold bootstrap.


Why do you keep saying C? Mold was C++ with some dependencies like TBB or zstd.


Too many years at Google where the two terms are most often used interchangeably; which is imprecise, but most of the time it doesn't matter. Forgive me for being imprecise here.

The fact remains that rust adds yet another toolchain to the boot process that needs trust and verification.



Maybe that's about to flip. Maybe Rust will be built first, followed by C.


Sorry to break it to everyone but Rust depends on python which depends on perl and openssl and the majority of any lean full source bootstrapped toolchain tree.

Unless the gcc rust engine is mature any time soon (lol), we have no path to use rust until very late game in a distro build.

The earliest we can bootstrap a go compiler is about 10 minutes. It builds directly from tinycc. Add 6 hours for our fastest compile of the shortest path to rust, with 192 cores.

I am a rust fan too, but it is the worst language to bootstrap, which is why for systems programming I still must often revert to C to have a small and reviewable and fast to build dependency surface.


Rust requires LLVM (or GCC) which requires C++, not just C.


LLVM is the default yes, there is also an experimental cranelift backend, which is all Rust. Not sure if it is good enough to build the compiler itself using it.

(There is also a GCC backend called codegen_gcc that is pretty far along. And a separate reimplementation of both the frontend and backend using gcc and C++, called gccrs, which is not nearly as far along.)


I'm pretty sure it does not support enough features to build the compiler (e.g. inline asm is not supported at all), and it will also be very, very slow to unusable.


Cranelift is supposed to compile without optimizations (-O0) faster than the regular Rust compiler, and supposedly, the code runs at about the same speed as regular -O0 compiled code. That generally means 2-5x slower runtime performance, which is just fine for bootstrapping.


I've never tried to bootstrap rustc with cranelift. I think some people did, not sure what were the results. I do know that bootstrapping rustc with -O0 is so slow it's essentially impossible even for just one bootstrapping step. -O1 might be possible.


Maybe it should be rewritten in Rust then


There are literally thousands of compiler engineers who pore over the assembly a compiler generates, and then finds ways to make it better. I get paid to figure out where the compiler can do better, and often a step in that is to hand-code my own replacement. I then teach the compiler to do that.

But even beyond that, the compiler can't make certain assumptions that an assembly writer can. Such as whether a callee-saved register really does need to be saved in some particular routine. Or even pushing an extra parameter in unusual cases.

So it is entirely possible to beat the compiler, it's doable under certain circumstances, even today.

But you also have the danger of your loving hand-crafted assembly beating the compiler today. But next year the compiler is even smarter, the hardware may have changed in subtle ways, and the compiler will know and improve the code it generates.

Your hand-written code won't change unless you revisit it.


What do you think the most impactful savings from hand-written assembly are over optimized Rust today?


1. Better memory locality by knowing what you load and when, exactly.

2. The ability to "cheat" on calling conventions.

3. The ability for techniques like threaded code, and in general, better cache-awareness.

4. Less mov's.

5. Guaranteeing no spilling in important loops.

6. Compilers don't do well with flags registers and you can't read/write them in high level languages. You're hoping your `if (result < a) { carry = 1; }` becomes a direct flag test. Especially important in bignum, you can't really utilise adcx/adox directly from high-level code.

7. Hot/cold layout without PGO. Yes PGO is good but sometimes you know better and PGO isn't very suitable for "configurable" code.

8. Computed goto. See https://github.com/python/cpython/issues/128563 , who doesn't like 10% free performance?

9. Exploiting uninitialised memory for classic party tricks like not initialising a buffer fully (let's say you have a library function with a return buffer. You don't want dynamic allocations for some reason. You can simulate this with a pointer return into a let's say a static 4KB buffer and a count return, you only initialise it until the count. Caller has the responsibility not to overread.)


All fair, but just to note on the "who doesn't like 10% free performance", that bug has the following note:

CORRECTION NOTICE: We've since found a compiler bug in LLVM 19 that artificially boosted the new interpreter's numbers. The numbers are closer to geomean 3-5% speedup. I apologize for reporting incorrect figures previously due to the compiler bug.


An optimizer is trying to balance between compile time, runtime speed, and code size, and most optimizations will win you one axis at the cost of one or both of the other axes. (The rare optimizations that win on all 3 are already all implemented in the compiler.) Compiler developer time is also a scarce resource; I know of so many more optimizations I could implement, but without demonstrable code that would actually benefit, it's not a good use of my time to implement them. Compilers tune this balance by making lots of heuristic decisions, and these heuristics are tuned by large benchmarks, which often times involve a lot of flat code profiles (i.e., no code is worth spending a lot of time really nailing down the best code layout).

One of the advantages of hand-written assembly is that you get to opt out of the compiler heuristics and commit to being able to spend the time to optimize the one bit of code that you know is really important for runtime as perfectly as you want, instead of relying on the compiler to get it close enough to perfect before it exhausts its budget of caring about optimizing it.


You can usually hint the compiler, but the best idea is to provide it with more data. PGO with real-world data and LTO for whole-program analysis enable it to do much better decisions.


usually with Rust impactful savings come from writing the Rust differently, not from doing hand-written assembly instead.

See stuff like https://davidlattimore.github.io/posts/2025/09/02/rustforge-...

This doesn't mean Rust is near perfect, it's just that your first move should be "how do I make the Rust better" and not "I need to drop into asm."


"We’d like to initialise our Vec in parallel, otherwise we’d have to wait for the main thread to fill the entire Vec with a placeholder value only to then have our threads overwrite those placeholder values."

Talk about overengineering :P Multithreaded vector initialisation instead of just...skipping it?


That sentence is specifically talking about not initializing with a placeholder value, and instead letting it write over uninitialized values.


With hand-written assembly, you can (with effort and care) ensure that the code runs in constant time and doesn’t leak any information through side channels (such as which memory or cache addresses it accesses). That’s important for most encryption code. It’s difficult to ensure constant time execution in pure Rust (or C, or most high level languages in general) because you can’t tell if some future compiler optimization will break your attempts at constant-time code.


As one example, LLVM still routinely does dumb stuff like this: https://github.com/llvm/llvm-project/issues/53348

Regarding ABI, calee-saved registers also often result in useless data shuffling and prevent the compiler from using them for argument/result passing.


With whole program analysis (LTO, usually, though not only), LLVM can create custom ABIs.


Hand-optimized assembly tends to be ephemeral. My codebase constantly changes, which means hand-written assembly had to be redone.

It's rarely worth the effort.

There a lot of juice in improving the data structures that a compiler cannot do.


Entirely situation and application specific. Just like with every other language.


So there's no patterns at all?


I'm so far downstream from the source language that I know of none specific to Rust. And note someone else's specific answer to your question above that has nothing Rust specific either.


Any “Multimedia Extensions” or streaming or whatever beyond what’s available past a 486.

Rust has autovectorization, but a developer knows their algorithms best.

Also AES-NI vs software is no contest.

When people talk about out coding ‘to the metal’ you have to consider what ‘the metal’ provides


As a compiler engineer, it's not hard to find opportunities for the compiler to produce better code. What's difficult is turning those into generalizable patterns without introducing bugs or regressing performance elsewhere. You're right that as time goes on hand-written assembly won't change, but I see that as increasingly less of an issue now that we have LLMs to pour over and re-analyze what's going on as new releases come out.


> Such as whether a callee-saved register really does need to be saved in some particular routine.

Ironically this is your preconceived abstraction of how a compiler has to operate. An ideal compiler could allocate registers differently for each called function: F1()->F2()->F3(), F1 uses r0-5, F2 uses r6-10, F3 uses r11-15, no register saving required in the whole chain. There's no need for a fixed ABI. Such a compiler would look very different from today's ones.


Modifying the ABI of a function requires being able to track down all of the call-sites of the function, which is less trivial than you might assume. ABI concerns also tend to baked in relatively early in the optimization pipeline because you just simply can't get the ABI wrong, and I can think of several instances where the ABI decision causes missed optimizations.

There is also the other issue that a good algorithm for optimizing a problem like register allocation tends to be super-linear (e.g., quadratic), and if you shift the model from "allocate on a per-function basis" to "allocate all functions", the N in the O(N²) goes from "size of function" to "size of program," which is now suddenly a lot more compiler time spent for very modest gains. If register spilling across a function call is a noticeable component of runtime, then you're probably better off inlining that function in the first place!


One of the hardest parts of optimizations is not being penny wise and pound foolish. This sort of thing is a great example of that.

Additionally, a hard part is that all of this can change over time with new hardware! Some patterns that were crucial before everything gained branch predictors are irrelevant now, etc.


> penny wise and pound foolish

I love this saying. The general problem, optimizing the wrong metric, shows up all over the place.


Yeah, that's what MSVC and GCC did on x86, called "custom calling conventions" on MSVC and the regparm attribute on GCC.

All of these were dropped on x64, on x64 (and ARM) you get standard calling conventions for just about everything with proper unwind tables for functions.

It doesn't really "cheat" on the registers unless it inlines a function entirely. LLVM has support for custom calling conventions and pragmas to specify them, this is used by GHC on Haskell and other things, but it's practically unheard of in "normal" C/C++ code.


If it were practical and if there were significant performance benefits (on modern heavyweight CPUs) to tailoring the calling convention on a per-function basis, I'd expect to see it done in optimising JIT engines like Java HotSpot. As far as I know, they don't bother.

I'm no expert but I suspect jcranmer's comment has it right that you end up doing cross-function register-allocation while foregoing the other benefits of just inlining. I also suspect the payoff would be minimal on modern heavyweight hardware. I can see it making more of a difference on a very minimal embedded processor, or if optimising for the smallest binary possible.


This is already done in the form of deciding whether or not to inline a function.


Now I'm wondering if Claude can beat the compiler if I ever need to optimize something a bit more.


Where by "messing up his first job", you mean, "Intentionally leaked proprietary data in one of the stupidest ways possible, was caught, and apparently didn't learn anything from the event."


I can't speak to anyone else's sneers and disdain, but mine come from all the motivated reasoning surrounding them. One example:

'The Effective Ventures Foundation (EVF), which defines effective altruism as “using evidence and reason to figure out how to benefit others as much as possible”, decided £14.9m of its cash would be best spent buying Wytham Abbey, a 15th-century Grade-I listed manor house near Oxford.'

There were a lot of explanations about why that was the most effective use of funds, but every single one reads like motivated reasoning to me.

Examples like this abound.


The Sam Bankman-Fried debacle of pay off politicians and gamble the customer deposits to become very rich because EA probably falls in that category and gave it a bad name.


I dont really see how SBF and FTX success and then failure was enabled by EA. Seems like people commit financial crime all the time.

Some SBF Quotes

> "This dumb shit I said—it's not true. Not really. Every soul-searching, virtue-signaling thing I said was just part of the game."

> "Fuck regulators. They make everything worse. They don't protect customers at all."


I'm not sure it was but there was quite a lot of press coverage eg. https://www.vox.com/future-perfect/23500014/effective-altrui... which probabaly contributed to the sneer and disdain.


And still required by Utah law.


DraftKings does it in a way that is good enough to comply with California law, which doesn't require perfection.

This Utah law requires perfection.


Oh I see, "An individual is considered to be accessing the website from this state if the individual is actually located in the state regardless of whether the individual is using..." as mentioned in the injunction https://www.courthousenews.com/wp-content/uploads/2026/09/ay... So yeah the law would basically require everywhere to perform age verification, where the law says it only has to be "commercially reasonable."


that is the plan, to make everyone have to use utah law

underlying reason is hatred for free internet


More accurately, hatred of freedom of religion, but yeah.


This would mean throwing away a giant market for what are generally pretty niche use cases. Very cool use cases, sure. But not worth giving all those sales up in favor of gray-market importers.


Guidelines | FAQ | Lists | API | Security | DMCA | Apply to YC | Contact

Search: