HNHacker News
TopNewBestAskShowJobs

camel-cdr

2,245 karma · joined January 31, 2021

submissionscomments
camel-cdr··on RISC-V: They Should Have Known Better
> You shouldn't be sharing that

Ah, I suppose.

camel-cdr··on RISC-V: They Should Have Known Better
Edit: removed

Yeah, fusing is probably easier, if you already know what to fuse. On the other hand, if you want to fuse load pair on RISC-V you have the entire rename stage to figure out which uops can be fused independently of the rename stage, if fusion haopens after rename as well.

camel-cdr··on RISC-V: They Should Have Known Better
> 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.

No, every high performance core I know of cracks them at decode, some re-fuse some of them after rename (Apple). Because otherwise you would need to rename up to 4 destinations per rename slot, effectively 4xing your already limiting rename stage.

Cracking other stuff later in the pipeline isn't expensive.

camel-cdr··on RISC-V: They Should Have Known Better
The decoder decodes them into two or more internal instructions (uops).

Take for example a post increment load, which does a=mem[b++], notice how this writes to two registers. Handeling two writes (up to 4) would explode the stage after decode (rename). So high performance arm implementations generate two uops for this. But since the number of decoders is fixed and the number of rename slots as well, you now have alnost the same problem as in RISC-V with compressed instructions: the nth input to the rename stage can come from a variaty of outputs of the decode stage, so you need a large shuffle network, and propagate the uop counts from start to end.

Cracking is a lot cheaper, if you can do it later in the pipeline. E.g. the cheapest is if you can simply "replay" the instruction. That is, instead of removing the entry from the issue queue, when it starts executing, you decrement a counter and keep the entry to do something else next. But as I mentioned that doesn't really work with multiple write back.

camel-cdr··on RISC-V: They Should Have Known Better
I want to try looking at codesize for -Os builds with the different ISAs including the compressed variants you mentioned. As well as dynamic icount with overflow checking.

Do you have any specific project in mind that I could use for testing?

camel-cdr··on RISC-V: They Should Have Known Better
https://github.com/riscv/riscv-isa-manual/pull/3269
camel-cdr··on RISC-V: They Should Have Known Better
The RVA point releases don't add new mandatory features, so every RVA23 complient board is also RVA23.1 complient. They only add new optional extensions.
camel-cdr··on RISC-V: They Should Have Known Better
There is a very easy way to determine what hardware you are running on, it's the baseline of the OS.

Armv9-a doesn't mandate FP or SIMD support, but nobody does detection for those, why? Because it's required on the OS level. Similarly OS are moving their baseline to RVA23 so software can assume all of those instructions are available.

camel-cdr··on RISC-V: They Should Have Known Better
> And maybe 16-32-48-64 is worth it..

It is, with a prefix encoding, you can reuse the RVC decode path 1-to-1 and get the 48/64-bit instruction starts with a simple bitshift (or simply handle the 48/64-bit instructions via the fusion path). This seems to be the encoding direction RISC-V is headed in.

camel-cdr··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.

Arm uses complex instructions with multiple writeback, that require cracking, to improve code density. RISC-V uses a variable length encoding to improve code density. Both have anaougus decoding complexity, but RISC-V achieves higher code density, while impacting the cost of things before decode (how much, idk).

camel-cdr··on RISC-V: They Should Have Known Better
Nobody in high-performance does fixed-width instructions that allow lineary scaling parallel decoders. Arm basically requires certain instructions to be cracked into multiple uops before rename. That ends up analougus to decoding compressed instructions. RVC increases complexity before decode, how much that impacts things idk.
camel-cdr··on RISC-V: They Should Have Known Better
My disagreement with the article is mostly the following:

RISC-V is not an ISA, but an ISA generation framework.

If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.

RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.

---

In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.

The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.

camel-cdr··on RISC-V: They Should Have Known Better
My disagreement with the article is mostly the following:

RISC-V is not an ISA, but an ISA generation framework.

If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.

RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.

---

In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.

The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.

camel-cdr··on Credibility is the barrier to entry in silicon
RISC-V has higher code density than Arm and x86 and all three have a comparible uop density, but RISC-V has a slightly higher average instruction count. What more complex instructions are missing?
camel-cdr··on Thanks to social media, canned sardines are a scarcity on the supermarket shelf
can you share the data?

btw, how much protein do you consider recommended?

camel-cdr··on Beef and dairy drive 41% of biodiversity damage linked to global farmland
I wonder what substitute the average vegan consumes.

I often see these vegan meat substitute products as an on-ramp and people who are vegan for longer tend to use other things in their staple dishes.

camel-cdr··on Rust SIMD on the GPU
> twice the native vector width has ~20% better throughput

Yes, this is what I was saying, but twice the vector width of AVX-512 will perform horrible in SSE, which is why portable SIMD abstractions should make writing code relative to the native vector width simple.

> I pass in the vector width as a generic parameter like this:

> fn do_simd_stuff<const N: usize>(x: Simd<f32, N>) { ... }

My problem is that no portable_simd example code I've seen does this, which causes people to choose one specific N and run with that.

The second part of the problem is how you find the native vector length, so you can instantiate the generic function. IIRC this isn't even exposed in portable_simd and you have to use a seperate crate to get it.

camel-cdr··on Rust SIMD on the GPU
Except you can't use this in actual code, because either, as is the case in this example with f32x32, you run out of registers and spill all over the place. Or you aren't using your full vector register or could've gotten better performance by "unrolling" more often for the larger vectors.

If you use f32x16 (the avx-512 wisth), SSE now effectively has 4 registers to work with and will spill when doing anything beyond the most simple stuff.

The default should imo be relative to the native register width, so you can do 1x, 2x or sometimes 4x the native width, depensing on your register preasure.

camel-cdr··on Rust SIMD on the GPU
The create is called portable_simd.

There is no reason a portable_simd relu_dot implemention should need to specify the SIMD width.

But the design and documentation of portable_simd makes the fixed size syntactically easy/the default and the width agnostic code harder.

camel-cdr··on Rust SIMD on the GPU
I love how ever example of portable SIMD isn't portable.

They specifies a constant SIMD width so it's non-portable. Well, not performance portable, but why are we using SIMD again?

camel-cdr··on Advancing the price-performance frontier with GPT‑5.6
this type of thing usually means you are the product
camel-cdr··on Proving a human wrote something
Well, this explains who has the training data to fake it then.
camel-cdr··on Milk-V Jupiter2: RVA23-Compliant RISC-V SBC
It used to be $300 for the 8GB RAM version for the first batch in May/June. (16GB for $400)
camel-cdr··on The Zilog Z80 has turned 50
> So, why not just cover that flaw by adding a carry/overflow flag.

Actually, why not just have a single generic 1-bit flag?

You could still have cmp + branch, but now you put the comparison type into the cmp. This gives you a larger branch range again. A flag setting add/sub could also simply set that flag on carry. cmov works, some form of ccmp also works.

camel-cdr··on The Zilog Z80 has turned 50
> Well, cmov is absolutely possible without flags. You see such "select" instructions all the time on GPUs

Well, yes, because GPUs need 3r1w anyways, for fmadd, and because a dedicated cmov (blen/merge) is a lot more important in those workloads. RVV also has "cmov" vmerge and full predication in general.

RISC-V wants to avoid needing to 3r1w on the integer side.

> But it does require three input registers. One for a control value, plus the two options. And RISC-V has a thing about not requiring three input registers.... Yeah, I'm not a fan of RISC-V.

Arm also tried to avoid 3R1W on the scalar integer side. It's really only madd (on one or two ALUs) and some of the complex load/store ops, which are usually cracked.

My guess is that arm has 3R1W integer instructions, because they needed load/store pair for code density. That means they have to support renaming 3R1W integer instructions, so you may as well add integer madd. I don't think they would've added 3r1w if it wasn't for the complex load/stores.

> One of the other major advantages of flags is it allowed for a cheap third input to certain instructions (like cmov, adc, ccmp), without requiring a full 3R1W register file.

Exactlty. Although I don't think the 3R1W instructions increase the register file size that much, because it grows linear with read ports and you usually don't need the full read bandwidth on very wide cores, as you can do port stealing. I think it's mostly about rename.

> But MIPS already proved it was possible, and showed all the downsides, it did not need to be tried a second time with RISC-V.

I think it's a fine way to design an ISA, however Zicond should've been on the base ISA.

camel-cdr··on The Zilog Z80 has turned 50
Designing an ISA arround carry flags certainly gives you many goodies: cmov, adc, ccmp, larger branch range
camel-cdr··on The Zilog Z80 has turned 50
That seems like a weird thing to save on, for architectures that have expensive but rarely used things like CLZ on all ALUs.

But I hadn't considered the ISA design option of only carry flag, no seperate cmp and branch, before.

camel-cdr··on The Zilog Z80 has turned 50
> Out-of-order pipelines actually have a really elegant way of handling flags, they just store a copy of the flags register on every ROB entry.

And yet, flag writing instructions are usually half the throughput on regular ALU instructions, on modern wide ooo designs. [1, 2]

But I generally agree, there is a good way of handling them, it's hust unclear to me how expensive it is. It can't be that expensive, but apparently it is expensive enough, to not put a mask register write port on all integer execution units.

[1] https://dougallj.github.io/applecpu/firestorm-int.html (see how ADD is 6-issue and ADDS 3-issue)

[2] https://developer.arm.com/documentation/111027/4-0/ (again 8-issue ADD, but 4-issue ADDS)

camel-cdr··on RISC-V Is Inevitable: State of the Union Keynote Argues
No don't buy this one, it doesn't support RVV. Their newer ones do, but those are a lot more expensive.
camel-cdr··on RISC-V Is Inevitable: State of the Union Keynote Argues
> Dart supports RISC-V as a target architecture for compilation, but I'm not really excited about figuring out how to map the wasm-SIMD-style primitives to RISC-V's RVV and so I don't really plan to look into it at all.

On the one hand, this will be quite straight forward, but on the other hand quite disappointing.

Afaik Dart has a 128-bit only SIMD abstraction (so not performance portable by default). Since the base "V" extension mandates a mininum vector length of 128-bit, you can trivially make codegen work for all vector length, by simply setting vl to 128/elementwidth.

But as with x86, if your native hardware vector length is larger than 128-bit, you leave performance on the table.

> This is mostly because their approach to SIMD is so different, but also because I can't test it at all. Are there any RISC-V "machines"?

I'd recommend using qemu for initial testing.

Hardware wise, the cheapest option is the orange pi rv2, which has 8 SpacemiT X60 cores, which are in-order and support 256-bit RVV. The Zhihe A210 is also interesting, but way to expensive for what it is.

If you have a higher budget, I'd recommend the SpacemiT K3, which is the fist RISC-V SBC with RVA23 support. It is has 8 SpacemiT X100 4-wide out-of-order cores, with 256-bit RVV.

← PreviousPage 2 of 25Next →