HNHacker News
TopNewBestAskShowJobs

phire

8,882 karma · joined March 18, 2011

submissionscomments
phire··on RISC-V: They Should Have Known Better
But imagine the code density you could get combining both strategies.

> Arm uses complex instructions with multiple writeback, that require cracking, to improve code density.

While smaller cores have the option of cracking the multiple writeback instructions, many arm cores just pay the extra cost of having a 3 read, 2 write register file, so they aren’t actually cracking those instructions.

They do crack other instructions.

But the cracking seems to be more about ALU limitations (aarch64 has instructions that can do both a shift of any width and an add, but the ALUs might not support this, or only support smaller shifts of 1-3 bits (useful for addressing)

What this means is that despite the cracking, each μop in an aarch64 core is quite a bit more powerful than a typical RISC-V instruction (especially compressed instructions).

So to be competitive on backend performance, a high performance RISC-V is going to spend a lot of resources post-decode doing massive amounts of instruction fusion to try to get μops of similar capabilities to aarch64 (or just settle for simpler μops, and pay scheduling costs of more μops)

So the costs of the RISC-V compressed instruction approach aren’t just limited to pre-decode.

phire··on RISC-V: They Should Have Known Better
I don't agree with the argument.

By the time you have an out-of-order core, there is already so much shared state you have to synchronise, and you have a bunch of complex mechanisms for dealing with it. Adding a flags register doesn't really add any more complexity, it's just a small bit of extra state attached to it.

And we already have the solution, it's register renaming. We are already renaming all the GPRs and FPRs, and we are probably also renaming part of fscr (because turns out, RISC-V does have flags for floating point operations), maybe a few other bits of state. So we just use the existing renaming mechanism to rename a bank of flags registers; That single logical shared flags register is actually backed with a bank of non-shared physical flags registers, neatly solving all concerns.

Sure, the renamed flags do take up a bit of die space. But IMO they don't add any extra design complexity, and shouldn't have any performance impact on maximum clock speed.

RISC-V isn't quite as disadvantaged by the lack of flags as some might suggest (and I wouldn’t say the lack of flags is RISC-V’s worst aspect), but there are a few sequences (add-with-carry, some conditional-moves, detecting overflow) where RISC-V is forced to burn an extra instruction or two to deal with the lack of flags, and IMO eliminating that would be worth the cost of slightly more die space.

Also, avoiding the need for dedicated compare-and-branch instructions would free up encoding space for other things (including larger range on branches)

phire··on RISC-V: They Should Have Known Better
The annoying thing about RVC is that 32-bit instructions can now appear misaligned. I would be far less annoyed about RVC if it didn't break alignment, as you could solve the problem with a bunch of RVC-only decoders at the misaligned offsets.

So you either need (almost) double the number of full decoders, or a length decode and a bunch of shifters to get each decoder the right input bits (which get larger the wider the front end is. The 8th instruction can be at one of 7 possible offsets)

phire··on RISC-V: They Should Have Known Better
> and RV64GC already clearly beats x86-64 in .text density.

Maybe I'm misremembering. Or maybe the numbers I'm remembering took into account the fact that most compilers unroll more aggressively on x86 than on targets they consider to be "embedded" (another pet peeve of mine)

I stand by my assessment that the code density of rv64gc (and especially rv64g) is lower than it would be if they had actually put a focus on code density.

> A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that.

Not sure I would say 16-32 is simple, certainly massively simpler than x86. My point is that you have already paid the tax for going variable length, and 16-32-48 isn't that much more complex. And probably worth it for 32-bit immediate/offsets.

And maybe 16-32-48-64 is worth it... Hard to tell, but I wouldn't entirely rule it out without study. The advantage would either be immediates/offsets that are too big to fit in 48 bits. Or some kind of VLIW style scheme which actually packed three 20-bit instructions into aligned 64-bit packets. (Or other mixtures of sizes like 30-30, 30-15-15, 40-20, or 15-15-15; We are talking about a complete break from RISC-V. There is a thread somewhere on HN where we brainstorm something like this).

But beyond that, no point really. Just pointing out that RISC-V reserved the space.

Maybe I need to prototype the 64-bit aligned packets idea someday, at least far enough to get instruction density numbers.

phire··on RISC-V: They Should Have Known Better
Don't forget:

3. You are writing a kernel, with large amounts of inline assembly

4. You are writing a compiler, either offline or online

5. You are writing embeddable blobs that don't know what platform they will be running on.

6. You are designing a RISC-V core, and need to decide which extensions you should be supporting for your intended use-case.

phire··on RISC-V: They Should Have Known Better
I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.

The important point is that there is no reason why a 16-bit/32-bit encoding shouldn't have smashed Aarch64's 32-bit only code density.

My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.

phire··on RISC-V: They Should Have Known Better
Yes... but then you are kind of wasting a pipeline stage on nothing more than length decoding.

I suspect a design with a full decoder every 16-bits might actually win on everything but gate count, mostly because it can deal with variable length instructions and variable number of μops per instruction in the same step. A decoder that doesn't output a μop because it was clobbered by a previous instruction, can be handled the same was as a decoder that didn't output a μop because of μop fusion.

Actually, that approach might actually eliminate the need for the extra pipeline stage (just at the cost of gates).

It's certainly not a deal breaker. But it's a valid criticism of the ISA.

phire··on RISC-V: They Should Have Known Better
The fact that it's only "competitive" with aarch64's code density is a solid black mark against RISC-V.

The only reason it's "competitive" is the compressed instructions, which means it's paying all the costs of variable length instructions, yet only getting marginal benefits. IMO a modern ISA taking advantage of variable length instructions should be able to absolutely smash the code density of a fixed width ISA like aarch64. At minimum, it should be competitive with x86 code density, if not smashing that too (because x86 has a lot of legacy baggage)

Compressed instructions aren't a bad idea for very small cores. They give you a decent code density boost with minimal added complexity.

But for large cores you either want to go full fixed length (like AArch64 and Qualcomm's proposal, which bought non-compressed RISC-V into the range of AArch64) or adopt a much more complex variable length scheme that can actually beat x86 on code density.

phire··on RISC-V: They Should Have Known Better
I'm not sure the gate count argument works in RISC-V's favour.

While RISC-V is quite optimised for gate count for small cores; In large wide OoO cores the variable length encoding really bulks out the decoders.

You basically have the same requirement as x86, where you have to attempt to decode a 32-bit instruction every 16-bits (because there is no alignment guarantee for 32-bit instructions), and then cancel out the invalid ones. It's not quite a bad as x86, you only need to look at two bits, but it still forms a long dependency chain, and probably requires at least one extra decode stage with complex routing to pick out all the valid instructions.

phire··on RISC-V: They Should Have Known Better
Yeah, very much legally distinct MIPS, at least as a starting point.

The biggest tell is the mnemonics. While RISC-V takes a bunch of ideas from other places, and cleans things up, it copies a lot of mnemonics straight from MIPS.

But it also copies a lot of other ideas from MIPS, like the absolute distain for flag registers.

phire··on RISC-V: They Should Have Known Better
And personally, I'm not even sure it crosses that bar.

RISC-V somehow manages to be more fragmented than x86 (which is impressive), and just can't compete on instruction density.

I think a large part of the issue with RISC-V is that it predates (public knowledge of) ARMv8 by a year or two, so it couldn't use it as inspiration. If you compare RISC-V to 32-bit ARM, the comparisons are much more favourable.

phire··on RISC-V: They Should Have Known Better
Considering just how many of the problems seem to come from RISC-V being a clean-sheet design, I suspect we would be better off not doing another.

What I am interested in is the idea doing an AArch64 style revamp of the ISA, were much of the non-encoding semantic stuff is kept, but the entire instruction encoding (plus all the CSRs, and other things) are reworked to be sane.

You might even do two reworkings in parallel, with one variable-width encoding optimised for microcontrollers, thumb-style; And the other being a fixed-width encoding optimised for wide out-of-order cores.

And at the same time, you make a bunch of extensions mandatory, and unify others into bigger chunks; Code compiled to one of these two encodings would know it had access to a much wider range of instructions.

The idea would be that any C code targeting RISC-V can be compiled to this encoding with close to zero changes, and that mechanical translation of exiting RISC-V binary code should be "possible", as none of the underlying semantics have changed. And the same would help any core wanting to natively support both (or all three) encodings, you would only need a front-end translator.

phire··on an ambiguity in C89 which will never be fixed
Not sure about later versions, but c89 doesn't seem to forbid casting a function pointer to a data pointer (it does say that casting pointers has implementation defined aspects, so lisp machines aren't out of spec if they fail).

The reason you can chain unlimited ''s is that f isn't actually a function pointer, it's a function designator. Function designators are automatically converted to function pointers in almost every case, but '' is special cased so that indirecting a raw function designator results in another function designator.

Edit: Actually on a closer reading, maybe it does. C89 doesn't explicitly point it out as forbidden or undefined, it simply defines two classes (objects and functions) and only defines a very limited set of valid operations on pointers to functions.

Though one operation that is implementation defined is converting a pointer to an int, and an int to a pointer. So with two steps through an implementation defined path, you have a data pointer to a function.

phire··on an ambiguity in C89 which will never be fixed
In c89, there doesn't seem to be any distinction between pointer to functions and pointer to data.

Do you know what c89 does explicitly say is undefined? Any pointer arithmetic at all (or array subscripting) for pointers are not pointing to a member of an array. It's already invalid to do pointer arithmetic a pointer to a struct.

Not that it matters for this. This isn't doing pointer arithmetic, f is simply the identifier for the array of "sizeof(f) ints" that make up the function argument. The identifier is optional for a function declaration.

phire··on Nine PBS sues Iron Mountain over blocked access to archival data
I’m not sure this is the only copy of the data.

Sounds like they paid a company to digitise all their old tapes, and store the results. They possibly still have all the tapes (on site) and are just trying to avoid paying the costs to redigitise them.

But, it’s also quite likely they destroyed all original the tapes after digitisation, and this was the only copy.

phire··on CFTC declares market emergency, orders Kalshi to continue to operate in New York
I think what the CFTC are arguing is that offering contracts in 49 states (everywhere except New York) is not "Nationwide".

So yes, technically the restraining order is preventing Kalshi from offering Nationwide contracts.

phire··on 2027 memory capacity is reportedly sold out
IMO, dicing counts as part of packaging. So before the dicing step of packaging.
phire··on Picophysics: Single file physics for games on platforms like N64, PSX, DC
The N64's FPU will usually be faster than doing fixed point on the CPU.

You are actually multiplier/divider bound, and the CPU can multiply about 10 bits per cycle and only divide 1 bit per cycle. Since you aren't multiplying the sign/exponent bits, it's faster to multiply/divide the 24 mantissa bits of a 32-bit float than it is to multiply/divide the 32 bits of an int.

And with fixed point, you then have to throw in the extra shift instruction (which floating point automatically does internally).

Though, this only applies to fixed point on the CPU. The RSP has no FPU, but it does have a 128 bit vector unit with 8 16bit lanes which is pretty good at fixed point stuff. If you can vectorise your algorithm, it will be faster on the RSP.

phire··on The Alpha 21264 CPU: NT's Greatest RISC (1998)
My understanding is that after Compaq sold the Alpha IP to intel, and quite a lot of the DNA ended up in Nehalem and Sandy Bridge.
phire··on 2027 memory capacity is reportedly sold out
I'm not even sure inspection and quality control is done at the fab.

At least with logic ICs, they either testing/QC/bining as part of packaging (before dicing), or even have factories that specialise in just testing/QC/Binning. Such fallacies need to be flexible enough to deal with thousands of different IC designs, and there is no reason to tie them to a given process node.

I guess with memory, there are only three-ish designs (DDR, LPDDR, HBM), so maybe it does make sense to integrate testing/QC/binning into the fab.

But I doubt they would have any trouble switching it out.

phire··on Microsoft Edge is about to lock out older ad blockers, just like Chrome did
Yeah, and you can change the defaults of UBO lite to always have full access to every site.
phire··on Microsoft Edge is about to lock out older ad blockers, just like Chrome did
There is a dynamic API too that allows extensions to modify the blocklist at runtime.

I’ve been using UBlock Origin Lite on my iPhone for a while, and that works great, keeping itself updated from EasyList and allowing for custom rules.

In some ways it’s better, in some ways it’s worse. Sometimes you have to flip it into “complete mode” (and give it full access to modify the current site) to get good blocking.

phire··on Hardware backdoors in some x86 CPUs
Not really... backdoor just means something that can bypass the main security.

It's just that publicly known backdoors are of very limited usefulness, because people go out of their way to remove, disable, or avoid them. Or worse, use them for their own gains. There have been more than a few cases of governments trying to implement and enforce publicly known backdoors (with keys only the government knows), such as the Clipper cryptography chip in the 90s.

But... just because something is documented, doesn't mean it's publicly known. We have an example here of something obscure enough to be a useful backdoor (assuming someone knew about it).

And while the underlying feature might have been documented, the fact that many BIOSes enabled the feature was not documented anywhere. That does count as hidden.

phire··on Hardware backdoors in some x86 CPUs
"It's documented in the datasheet" is such a weak excuse for a backdoor.

Documenting a backdoor doesn't make it not a backdoor, just means it's not a hidden backdoor.

The fact that a number of machines shipped with the backdoor accidentally enabled, and nobody noticed for over a decade shows just how dangerous even a documented backdoor can be. The oversight wasn't even detected by someone reading the manual, it was detected by a security researcher who wrote a generic tool to fuzz out such backdoors.

phire··on Assembly Hall of Shame
The repo page says exactly why these long running instructions were researched.

A very long-running instruction can be used to break SMI: https://github.com/xoreaxeaxeax/smiiiiiiiiiiiiiiii

phire··on Assembly Hall of Shame
It's actually benchmarking 1000 repetitions of the RDTSC instruction running in parallel.

My guess... On Skylake, multiple in-flight RDTSC instructions slow each other down for some reason?

Possibly because it's attempting to provide a strict monotonic guarantee, that no two RSTSC instructions will return the same timestamp. Intel's manual only claims monotonic, which theoretically allows for two RSTSC instructions to return the same timestamp.

phire··on Assembly Hall of Shame
As specified by the spec, it arguably increments RIP by one.

The actual typical hardware implementation just fetches the next 16-32 bytes from icache, shifts it to the correct alignment, and slams it into a bunch of parallel decoders which each attempts to decode one x86 instruction per byte.

The next cycle, the first 1-6 non-overlapping valid instructions are accepted into a queue for further decoding. The NOP almost certainly takes up space in this queue.

At no point does RIP get incremented by one. There isn't even a single physical RIP register to increment, the CPU is "executing" dozens or even hundreds of RIPs in parallel.

phire··on 2027 memory capacity is reportedly sold out
Even if they need to replace every single lithography machine, there are a lot of other machines that probably don't need to be replaced for any given upgrade.

Like everything related to it being a clean room; All the logistics robots which move wafers around; All the machines that deposit layers of material like CVD/AVD/Sputtering; The various machines that do the actual etching; The furnaces; The inspection and quality control equipment;

Also, absolutely everything to do with dicing and packaging. But that's usually already at another factory (often a completely different company) due to how process agnostic it is. Same applies to growing and prepping the silicon wafer.

phire··on 2027 memory capacity is reportedly sold out
There is some overlap. The last DDR4 fabs were typically on a 16nm process, the first DDR5 fabs were also on a 16nm process.

There shouldn't be much issue converting those 16nm DDR4 fabs to DDR5, it's really just an issue of swapping out the masks. That's assuming they haven't all already been converted years ago.

Even when there isn't an overlap, moving to the next process node usually isn't so much about replacing machines, but adding more machines. To oversimplify, you might not be able to convert one older DDR4 fab to DDR5, but sometimes you might be able to convert two older DDR4 fabs to one DDR5 fab.

Such conversions might not be the most cost-effective option in the long run (that unmodified fab could have kept selling DDR4 for years), but conversions might be significantly faster than building new fabs.

phire··on Branchless Rust: Making a Filter 4x Faster by Removing an If
> Before dynamic branch prediction... static branch prediction had been used for decades.

I'm not sure that's true. At least not the "predict backwards branches are taken" part.

Many RISC cpus did kind of have "predict forwards as not taken", but really thats just speculative execution with the complete absence of any branch prediction at all. IMO "All branches are not taken" is not a prediction.

Actual Static Branch prediction is something that seems to have shown up at the exact same time as dynamic branch prediction (ie Pentium and PowerPC 601). Seems to be more of a "well do speculative execution now, what do we do when there is no dynamic prediction?" thing.

Maybe there is a multi-chip CPU out there that has proper static prediction but not dynamic? But I checked the likely candidate (The RS/6000 aka POWER1) and it doesn't have any prediction at all (just a hole where the static prediction bits will go later). Probably because static prediction requires support for speculative execution, which it doesn't do.

← PreviousPage 3 of 34Next →