HNHacker News
TopNewBestAskShowJobs

mbitsnbites

383 karma · joined March 21, 2018

submissionscomments
mbitsnbites··on How to make Firefox builds 17% faster
Same with BuildCache, except you also get a fast local cache so you effectively have an L1 and an L2 cache.

In fact, since you also have super fast "direct mode" caching that bypasses the preprocessor (like ccache but unlike sccache), BuildCache really has three logical levels of cache: direct, preprocessor and remote (S3, redis, ...).

mbitsnbites··on How to make Firefox builds 17% faster
Though I'm not actively working with Firefox so can't speak for their use cases, one important use case for clobber builds is CI.

I'm the author of BuildCache, and where I work we make thousands of clobber builds every day in our CI. Caching helps tremendously for keeping build times short.

There are a few use cases for local development too. For instance if you switch between git branches you may have to make near full rebuilds (e.g. in C++ if some header file is touched that gets included by many files).

Another advantage as a local dev is that you can tap into the central CI cache and when you pull the latest trunk and build it, chances are that the CI system has already built that version (e.g. as part of a merge gate) so you will get cache hits.

mbitsnbites··on How to make Firefox builds 17% faster
For what it's worth, browser uptake is largely dictated by the browser being default shipped with some major OS. Very few users make an active choice (statistically speaking).

Safari is popular because it ships with iOS and macOS.

Edge (previously IE) is popular because it ships with Windows.

Chrome, however, is popular for several reasons. One reason is that it ships with Android and ChromeOS, but before that Google had a very aggressive multi-channel campaign where they pushed it with large banners on Google search (everyone used Google) and they made deals with Windows AV vendors so that when a user installed anti-virus on their computer Chrome was automatically installed and made the default browser. Another reason is that Google has consistently develeoped Chrome together with their web services, so things like search, maps, gmail, docs etc tend to work best in Chrome.

The only default channels that Firefox has, that I'm aware of, are verious Linux distros, and they have a pretty thin market slice.

mbitsnbites··on How to make Firefox builds 17% faster
And a local cache (kind of level 1 and level 2 caches)
mbitsnbites··on Show HN: A luma dependent chroma compression algorithm (image compression)
Just a note for the posterity: The continuation of the project is called Bitfrost CC and lives here: https://codeberg.org/mbitsnbites/bitfrostcc
mbitsnbites··on Show HN: A luma dependent chroma compression algorithm (image compression)
Thanks for the references! After writing the blog I was looking for such references.
mbitsnbites··on Show HN: A luma dependent chroma compression algorithm (image compression)
Thanks for the feedback, and the interesting ideas. It's good to know that I was on to something and not completely off :-)

I'm mostly doing this for learning purposes, but a hidden agenda is to create a low-latency codec that can be used in conjunction with other codecs that deal primarily with luma information. AV1 and friends are usually too heavy in those settings, so I try to keep things simple.

mbitsnbites··on Show HN: A luma dependent chroma compression algorithm (image compression)
I truly get that. That's also one of the reasons why I started from scratch once I got the idea, rather than researching all the available papers and implementations etc (because the latter is quite overwhelming, while the former took me about a week of spare time hacks).

My scope is also a bit unusual, I think, because one of the applications I'm thinking about is to "augment" luma-only codecs with chroma. One such codec is https://gitlab.com/llic/llic

But most of all, I wanted to learn.

mbitsnbites··on Zed now predicts your next edit with Zeta, our new open model
The model is based on Qwen2.5-Coder-7b it seems. I currently run some quantized variant of Qwen2.5-Coder-7b locally with llama.cpp and it fits nicely in the 8GB VRAM of my Radeon 7600 (with excellent performance BTW), so it looks like it should be perfectly possible.

I would also only use Zeta locally.

mbitsnbites··on Reciprocal Approximation with 1 Subtraction
When measuring the errors I exhaustively iterate over all possible floats in the range [1, 2), by enumerating all IEEE 754 single precision representations in that range. That's "only" 2^23 numbers, so perfectly doable.

My selection criteria was abit complex, but something like this:

1. Maximize number of accurate bits in the approximation.

2. Same in NR step 1, then NR step 2 etc.

3. Minimize the max error in the approximation, and then the avg ertor in the approximation.

4. Same for NR step 1, 2, ...

mbitsnbites··on Reciprocal Approximation with 1 Subtraction
Given my search criteria, the optimal magic number turns out to be: 0x7ef311c2

  Initial approximation:
    Good bits min: 4
    Good bits avg: 5.242649912834
    Error max: 0.0505102872849 (4.30728 bits)
    Error avg: 0.0327344845327 (4.93304 bits)

  1 NR step:
    Good bits min: 8
    Good bits avg: 10.642581939697
    Error max: 0.00255139507338 (8.61450 bits)
    Error avg: 0.00132373889641 (9.56117 bits)

  2 NR steps:
    Good bits min: 17
    Good bits avg: 19.922843217850
    Error max: 6.62494557693e-06 (17.20366 bits)
    Error avg: 2.62858584054e-06 (18.53728 bits)

  3 NR steps:
    Good bits min: 23
    Good bits avg: 23.674004554749
    Error max: 1.19249960972e-07 (22.99951 bits)
    Error avg: 3.44158509521e-08 (24.79235 bits)
Here, "good bits" is 24 minus the number of trailing non-zero-bits in the integer difference between the approximation and the correct value, looking at the IEEE 754 binary representation (if that makes sense).

Also, for the NR steps I used double precision for the inner (2.0 - x * y) part, then rounded to single precision, to simulate FMA, but single precision for the outer multiplication.

mbitsnbites··on Reciprocal Approximation with 1 Subtraction
The big cores do. They essentially pump division through something like an FMA (fused multiply-add) unit, possibly the same unit that is used for multiplication and addition. That's for the Newton-Raphson steps, or Goldschmidt steps.

In hardware it's much easier to do a LUT-based approximation for the initial estimate rather than the subtraction trick, though.

It's common for CPUs to give 6-8 accurate bits in the approximation. x86 gives 13 accurate bits. Back in 1975, the Cray 1 gave 30 (!) accurate bits in the first approximation, and it didn't even have a division instruction (everything about that machine was big and fast).

mbitsnbites··on Reciprocal Approximation with 1 Subtraction
We have memcpy behind a C++ template function that mimics the interface of std::bit_cast.
mbitsnbites··on Reciprocal Approximation with 1 Subtraction
Your suggestion got me intrigued. I have a program that does an exhaustive check for maximum and average error, so I'll give your numbers a spin.
mbitsnbites··on Reciprocal Approximation with 1 Subtraction
If you're not constrained to software solutions you have a whole world of opportunities. E.g. if it's a graphics or neural net pipeline you can pour tricks like this (or better) onto it. If it's a CPU then you can add special instructions that do exponent manipulation and the likes.
mbitsnbites··on Reciprocal Approximation with 1 Subtraction
Excellent! Will have a look.
mbitsnbites··on Reciprocal Approximation with 1 Subtraction
There is also the case with machines that lack FP support, like some ARM Cortex M variants.
mbitsnbites··on Reciprocal Approximation with 1 Subtraction
The proper solution is to use std::bit_cast in modern C++ or otherwise use memcpy, and of course know what you're doing.

Some things that could mess with you:

* Floating-point endianity is not the same as integer endianity.

* Floating-point alignment requirements differ from integer alignment requirements.

* The compuler is configured to use something else than 32-bit binary32 IEEE 754 for the type "float".

* The computer does not use two's complement arithmetic for integers.

In practice, these are not real problems.

mbitsnbites··on Reciprocal Approximation with 1 Subtraction
Yep. Along the same lines. This one is even simpler, though, as it requires only a single integer CPU instruction (and the simplest of all instructions too).

If you want full precision, you need to do three Newton-Raphson iterations after the initial approximation. One iteration is:

    y = y * (2.0F - x * y);
mbitsnbites··on Kronos: Soviet Processor Family for High-Level Languages (2006) [pdf]
I'd argue that x86 and IBM z/Arch are the ones that stick out among contemporary ISAs in that they need fairly complex fron-end translation into an internal instruction format.

ARM implementations that support both ARMv7 (both ARM mode and THUMB mode) and ARMv8 also need some kind of translation in the front-end, but recent ARMs (like Apple's implementations) don't support 32-bit mode and are simpler in that way.

Most other ISAs are much closer to the metal, although many implementations still do some level of translation in the front-end (mostly fusing/splitting certain instruction combinations for better efficiency). Examples: ARMv8+, RISC-V, MIPS, Loongson, TI 6x & 7x DSP, and of course most GPUs (and my own MRISC32 ISA).

mbitsnbites··on Yes, social media is a cause of the epidemic of teenage mental illness
People are ignorant. Companies are greedy. That's why we need regulation.

Children don't need social media, just as they don't need tobacco or alcohol. As long as all your friends are off social media, you'll be fine. It's when there's a choice that you get the FOMO situation that makes it more or less impossible for parents to dissuade their children from using social media.

mbitsnbites··on ZX Spectrum Raytracer
Yup. Everything pre-RISC was CPI (Cray doesn't count - it was effectively RISC, and way too expensive anyway).
mbitsnbites··on Florida House of Representatives approves bill to ban social media for kids < 16
> government doing a parent's job

The problem here is that it's pretty much out of the hands of the parents. If your kids' friends have social media, your kids will absolutely need it too in order to not be left out. I've witnessed the pressure, and it's not pretty. Add to that the expectation from society that children shall have access to social media.

Regulation is pretty much the only way to send the right signals to parents, schools, media companies (e.g. Swedish public service TV has a kids app that until recently was called "Bolibompa Baby", but it's now renamed to "Bolibompa Mini"), app designers, and so on.

mbitsnbites··on Florida House of Representatives approves bill to ban social media for kids < 16
> I'd like to see more science proving that social media is bad for kids

Smoking tobacco was allowed for children for hundreds of years before it was regulated. Today we can hardly fathom how stupid it would be to allow children to smoke. Social media is much more accessible than cigarettes, far more addictive, and rather than messing with your lungs it messes with your brain and personality.

There are many problems with "waiting for the science". One is that it takes many, many decades to get reliable longitudinal studies on things like addiction and how the brain is affected.

There are so many indications that social media is bad for children (including scientific studies), in many different ways. It really should not be controversial to limit use for children. It's not like it is something that they need.

This book, "Smartphone brain: how a brain out of sync with the times can make us stressed, depressed and anxious" by Swedish MD psychiatrist Anders Hansen, brings up one of the aspects (unfortunately I don't know of an English translation): https://www.amazon.se/Sk%C3%A4rmhj%C3%A4rnan-hj%C3%A4rna-str...

Here's a short video with Anders Hansen: https://youtu.be/DwAx2kRwCRI?t=112

Then there's is of course the question of how to limit the use. But that's another issue.

mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
BTW, do you have any blog, public repos or anything else?
mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
> I like that term. Do you have any suggested reading material from Alsup?

He dwells in the comp.arch newsgroup, and is usually happy to answer questions.

His take on RISC: https://groups.google.com/g/comp.arch/c/UvprSM9xJfM

His ISA, My 66000: https://groups.google.com/g/comp.arch/c/SlbYDIPZjH0/m/CLkxJH...

Since he designed the Motorola 88000 ISA, I assume that he has a finger in the Mc88100 users manual: http://www.bitsavers.org/components/motorola/88000/MC88100_R...

He also has quite a few interesting patents: https://patents.justia.com/inventor/mitchell-alsup

> As I understand, the POWER1 is about the same as the PowerPC 601. There is no register renaming

Yes, it's a stretch to call it an OoO implementation with register renaming. I think that it does register renaming, but only for the FPU, and only in a very conservative way. Merely pointing out that OoO and register renaming weren't really pioneered in x86 architectures in the late 1990's. As usual, it's an incremental process, with no clear start.

> and the definition was muddy

And it still is ;-)

> This is also part of the reason why I want more terms than just RISC and CISC. Because the NexGen line is clearly not CISC either.

Agree. I think that many of the confusions are around ISA and microarchitecture. E.g. do all x86 CPU:s count as CISC, since the ISA is CISC? Does the internal uOP instruction set qualify as an "architecture" (ISA)? How about the decoded "operation packets" that flow down the execution pipeline? Can you even say that a microarchitecture is "RISC", or is that term reserved for the architecture?

I think I lack a good term for "a straight pipeline without loops" (or thereabout), which is kind of the original watershed between CISC and RISC, back when architecture and microarchitecture were still very intimately coupled (remember, CISC too exposed to much of the microarchitectural details, which is one of the main reasons that we have an "x86 tax" in the first place).

z/Architecture is an interesting extreme to bring into the mix, since even though it does pipelining, most of the implementations have a fairly complex "graph" rather than a straight line (AFAICT). It can't be made to resemble RISC even if you squint, whereas it can be hard to tell the pipelines for AArch64, POWER9 and x86-64 implementations apart at a quick glance: They all have a very clear and straight flow.

> this conversation is very helpful for thinking though things

Exactly :-) I love these discussions as I find that when I try to explain or argue a certain topic, many pieces fall into place, plus of course you pick up and learn tons from people like you who know a lot and clearly have given these questions some thought.

> but you are forgetting the scheduling, which adds massively to backend complexity, and makes a major impact to the overall microarchitecture and the design paradigms

I think I'm merely dismissing it as "yet another major technical improvement" (right up there with pipelining, caches, branch prediction, and superscalar execution). It surely is a major microarchitecture paradigm, and it does seem to be one that will stick for a long time, but I'm still reluctant to compare it to CISC or RISC, which in my mind talk more about the architectecture, whereas GBOoO talks more about the microarchitecture, and is largely ISA agnostic (these days). Gaah, it's hard. Going back to the question about ISA vs uarch again.

Anyway, this has been a very good talk. Thanks!

mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
> ARM weren't even targeting the ultra low end, as they have a completely different -M ISA for that.

That's the brilliance of it all, IMO. They didn't have to target the ultra low end, since they already had an ISA that works perfectly in that segment (the -M is basically a dumbed down ARMv7, but most of the ecosystem came for free).

Unlike...

> This is in contrast to RISC-V.

...which is a mistake IMO. When you want to be good at everything, you're not the best at anything.

Footnote: I am convinced that we'll see a fork (of sorts) of RISC-V for the GBOoO segment. Since the ISA is free, companies will do what they see fit with it. Possible candidates for this are NVIDIA and Apple (both known for wanting full control of their HW and SW), or possibly some Chinese company that needs a strong platform now that the US is putting in all kinds of trade restrictions (incl. RISC-V https://techwireasia.com/10/2023/do-risc-v-restrictions-sign...).

> And they apparently had a strong focus on code density.

This is also very interesting. At first you'd think that they abandoned code density when they dropped thumb, went for fixed width 32-bit instructions, and even dropped ldm/stm, but when you look closer at the ISA you realize that AArch64 code is very dense. From what I've seen it's usually denser than x86 code. I attribute a large part of this to many key instructions that appear to have been designed for cracking (e.g. ldp x29, x30, [sp], 48 - looks suspiciously crackable, it's really 2-3 instructions in one, and it has three (!) outputs).

So...

> You might hate me for this, but I have to raise the question:

Not at all :-)

> Does AArch64 actually count as a RISC ISA?

No. It has a few obvious traits of a RISC (it's clearly a load-store ISA with many registers), but it also has instructions that clearly were not designed with a 1:1 mapping from architecture to microarchitecture (which I would expect in a RISC ISA).

> I lean towards the opinion that this tight coupling between ISA and RISC microarchitecture is another fundamental aspect of a RISC ISA.

Yes, you have a point. When instructions are designed to decode into a single "internal instruction" that occupies a single slot in the pipeline (one instruction = one clock), we have a RISC ISA. That does not say anything about pipeline topology, though (e.g. parallelism, pipeline lengths, branch delays, etc).

There are obviously edge cases and exceptions that make a precise definition tricky. For instance, I consider MRISC32 to be a RISC ISA, but an implementation may expand vector instructions into multiple operations that take several clock cycles to complete (not entirely different from ldm/stm in ARMv7).

I think that we need to accept a sliding scale, instead of requiring hard limits. Hence the term "RISC-style", rather than "RISC". Perhaps some kind of a Venn diagram would make better sense :-)

> None of these attempts worked well ... the flaw was probably the statically scheduled VLIW

I still think that there is potential in software-aided decoding/translation (heck, most of the software that we run on a daily basis is JIT-translated, so it can't be that bad).

I think that Transmeta failed largely because they initially aimed at a different segment (high performance) but had to adjust their targets to a segment that wasn't really mature at the time (low power), and they didn't have a backup for catering to high performance needs.

However... If software decoding is only used for small power efficient cores (and maybe they use something else than VLIW?) that live together with proper high end cores on a SoC, then I think that the situation would be completely different.

IIRC a main driver for Transmeta was to circumvent x86 licensing issues, so even if big/little would be feasible at the time and they had the skills and manpower to pull off a high end x86 core, that would probably not be an option.

mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
Correction: Ok, the IBM z/Architecture line of CPU:s are clearly a different breed. In later generations they do use instruction cracking (i think that they were inspired by the x86 success), and insane pipelines:

https://www.semanticscholar.org/paper/History-of-IBM-Z-Mainf...

I struggle to find a categorization for the z15 - other than "massive".

mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
I see what your pointing at. I don't think that we'll fully agree on the nomenclature, but this kind of feels like the RISC vs CISC debate all over again. The reality is that the waters are muddied from the 1990's and onward.

I know that I have a tendency to over-use the word "RISC" (basically for anything that is not a 70's CISC state-machine).

> or they allude to overly broad definitions like "Everything that's not CISC"

Yup, that's me ;-)

BTW, w.r.t. nomenclature, I make a clear distinction between "architecture" and "microarchitecture" (even if I mix up contexts at times).

> But this does mean I'm arguing that anything with out-of-order execution is not RISC.

I think that this is where we disagree. E.g. the POWER1 (1990) was the first (non-mainframe) out-of-order CPU with register renaming, and it was a RISC. The Alpha 21264 (1998) was definitely both RISC and OoO. One of the first x86 implementations with uOPs translation, the NexGen Nx686 (1995, later AMD K6), was also out-of-order, and was said to have a RISC microarchitecture (based on RISC86). Not as complex as modern cores, but drawing the line at OoO does not work for me.

Historically RISC meant many things, and as you said the early RISC machines had many design quirks that did not stand the test of time (in particular exposing too many microarchitectural details in the ISA - something that proved useful in low-power VLIW DSP:s, though).

However, the key takeaway that has stood the test of time is an instruction set that enables fully pipelined execution. In the 70's and 80's, using a load-store (register-register) ISA was the only viable way out of multi-cycle instructions. To me, the principle to design instructions for pipelined execution is the main point of RISC, and the key point where it differs from CISC ISA:s, which were specifically designed for state-machine style microarchitectures (I don't have a better term).

In the 90's the same principles were implemented at the microarchitecture level (Nx586, K6, P6), without changing the architecture (i.e. the x86 ISA was kept on the surface).

Out-of-order happened to arrive to microprocessors at around the same time, so it was an obvious natural development for all high-performance CPU:s, regardless of "RISC" branding or not. It was the way forward to increase ILP (yes, you can do superscalar in-order too, but there's a rather annoying limit to parallelism there). It just so happened that cracking x86 instructions into multiple uOPs was a good way to make better use of OoO as well (in fact, that kind of cracking was exactly what was proposed by the RISC crowd in the 70's and 80's, but at the ISA level rather than at the microarchitecture level).

> I'm going to call this arch the "massively out-of-order" for now.

Mitch Alsup calls it GBOoO (Great Big Out-of-Order). There are some merits to making that distinction - but like you I would like to see a widely adopted definition.

Yet, I will continue to use terms like "RISC-like pipeline". I guess one of my main motivations is to make people understand that x86 is no longer CISC "under the hood". Especially with RISC-V being popularized, a new generation comes asking questions about RISC vs CISC (as in RISC-V vs x86), without understanding the difference between an architecture and a microarchitecture.

For most intents and purposes most GBOoO microarchitectures are comparable when it comes to the execution pipeline, regardless of which ISA they are using. The main differences are in the front end - but even there many of the principles are the same (it's mostly a question of how much effort needs to be spent on different parts - like decoding, prediction, caching).

mbitsnbites··on Quake on an FPGA (MRISC32 CPU) [video]
> I'm a huge fan of aarch64, it's a very well designed ISA

I totally agree. I would go as far as to say that it's the best "general purpose" ISA available today. I am under the impression that the design was heavily data driven, building on decades of industry experience in many different sectors and actually providing efficient instructions for the operations that are used the most in real code.

> I only really defend x86 because nobody else does

:-D I can easily identify with that position.

> I get the impression that Intel are planning to eventually abandon their P core arch

Very interesting observation. It makes a lot of sense.

I also think that we will see more hybrid solutions. Looking at the Samsung Exynos 2200, for an example from the low-power segment, it's obvious that the trend is towards heterogeneous core configurations (1 Cortex-X2 + 3 Cortex-A710 + 4 Cortex-A510): https://locuza.substack.com/p/die-analysis-samsung-exynos-22...

Heterogeneous core configurations has only just recently made it to x86, and I think it can extend the lifetime of x86.

For laptops, I can see an x86 solution where you have a bunch of very simple and power-efficient cores in the bottom, that perhaps even uses something like software-aided decoding (which appears to be more power-efficient than pure hardware decoding) and/or loop buffers (to power down the front end most of the time). And then build on top of that with a few "good" E-cores, and only one or two really fast cores for single-threaded apps.

For servers I think that having many good E-cores would be a better fit. Kind of similar to the direction AMD is taking with their Bergamo EPYC parts (though technically Bergamo is not an E-core, it gives more cores at the same TDP).

Page 1 of 4Next →