Live data from Hacker News

Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

box86.org

121–130 of 149 posts

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#121

Earlier quoted context omitted.

>and more about "don't add any assembly programmer conveniences or other such cleverness, rely on compilers instead of frontend silicon when possible" What are the advantages of that?

It shifts implementation complexity from hardware onto software. It's not an inherent advantage, but an extra compiler pass is generally cheaper than increased silicon die area, for example. On a slight tangent, from a security perspective, if your silicon is "too clever" in a way that introduces security bugs, you're screwed. On the other hand, software can be patched.

I honestly find the lack of compiler/interpreter complexity disheartening.

It often feels like as a community we don't have an interest in making better tools than those we started with.

Communicating with the compiler, and generating code with code, and getting information back from the compiler should all be standard things. In general they shouldn't be used, but if we also had better general access to profiling across our services, we could then have specialists within our teams break out the special tools and improve critical sections.

I understand that many of us work on projects with already absurd build times, but I feel that is a side effect of refusal to improve ci/cd/build tools in a similar way.

If you have ever worked on a modern TypeScript framework app, you'll understand what I mean. You can create decorators and macros talking to the TypeScript compiler and asking it to generate some extra JS or modify what it generates. And the whole framework sits there running partial re-builds and refreshing your browser for you.

It makes things like golang feel like they were made in the 80s.

Freaking golang... I get it, macros and decorators and generics are over-used. But I am making a library to standardize something across all 2,100 developers within my company... I need some meta-programming tools please.

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#122
post #117

Earlier quoted context omitted.

>and more about "don't add any assembly programmer conveniences or other such cleverness, rely on compilers instead of frontend silicon when possible" What are the advantages of that?

Instructions can be completed in one clock cycle, which removes a lot of complexity compared to instructions that require multiple clock cycles. Removed complexity means you can fit more stuff into the same amount of silicon, and have it be quicker with less power.

That's not exactly it; quite a few RISC-style instructions require multiple (sometimes many) clock cycles to complete, such as mul/div, floating point math, and branching instructions can often take more than one clock cycle as well, and then once you throw in pipelining, caches, MMUs, atomics... "one clock cycle" doesn't really mean a lot. Especially since more advanced CPUs will ideally retire multiple instructions per clock.

Sure, addition and moving bits between registers takes one clock cycle, but those kinds of instructions take one clock cycle on CISC as well. And very tiny RISC microcontrollers can take more than one cycle for adds and shifts if you're really stingy with the silicon.

(Memory operations will of course take multiple cycles too, but that's not the CPU's fault.)

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#123

Earlier quoted context omitted.

x86 instruction lengths range from 1 to 15. > a line of cache and 4 byte instructions you could start decoding 32 instructions in parallel In practice, ARM processors decode up to 4 instructions in parallel; so do Intel and AMD.

Apple's m1 chips are 8 wide. and AMD and Intel's newest chips are also doing more fancy things than 4 wide

Any reading resources? I’d love to learn better the techniques they’re using to get better parsllelism. The most obvious solution I can imagine is that they’d just try to brute force starting to execute every possible boundary and rely on it either decoding an invalid instruction or late latching the result until it got confirmed that it was a valid instruction boundary. Is that generally the technique or are they doing more than even that? The challenge with this technique of course is that you risk wasting energy & execution units on phantom stuff vs an architecture that didn’t have as much phantomness potential in the first place.

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#124

Earlier quoted context omitted.

Vector stuff is typically hand coded with intrinsics or assembly. Autovectorization has mixed results because there’s no way to request the compiler to promise that it vectorized the code. But for an emulator like this, box64 has to pick how to emulate vectorized instructions on RiscV (eg slowly using scalars or trying to reimplement using native vector instructions). The challenge of course is that typically you don…

I read somewhere that since floating point addition is not associative the compiler will not autovectorize because the order might change.

It’s somewhat more complicated than that (& presumed your hot path is floating point instead of integral), but that can be a consideration.

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#125

Earlier quoted context omitted.

Vector stuff is typically hand coded with intrinsics or assembly. Autovectorization has mixed results because there’s no way to request the compiler to promise that it vectorized the code. But for an emulator like this, box64 has to pick how to emulate vectorized instructions on RiscV (eg slowly using scalars or trying to reimplement using native vector instructions). The challenge of course is that typically you don…

> Vector stuff is typically hand coded with intrinsics or assembly. Autovectorization has mixed results because there’s no way to request the compiler to promise that it vectorized the code. Right, but most of the time those are architecture specific and RVV 1.0 is substantially different than say, NEON or SSE2, so you need to change it anyways . You also typically use specialized registers for those, not the general…

I’m highlighting that the compiler doesn’t automatically take care of vector code quite as automatically and as well as it does register allocation and instruction selection which are slightly more solved problems. And it’s easy to imagine that a compiler will fail to optimize a piece of code as well on something that’s architecturally quite novel. RISCV and ARM aren’t actually hugely dissimilar architectures at a high level that completely different optimization need to be written and even selectively weighted by architecture, but I imagine something like a Mill CPU might require quite a reimagining to get anything approaching optimal performance.

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#126
post #122
post #117

Earlier quoted context omitted.

Instructions can be completed in one clock cycle, which removes a lot of complexity compared to instructions that require multiple clock cycles. Removed complexity means you can fit more stuff into the same amount of silicon, and have it be quicker with less power.

That's not exactly it; quite a few RISC-style instructions require multiple (sometimes many) clock cycles to complete, such as mul/div, floating point math, and branching instructions can often take more than one clock cycle as well, and then once you throw in pipelining, caches, MMUs, atomics... "one clock cycle" doesn't really mean a lot. Especially since more advanced CPUs will ideally retire multiple instructions…

>quite a few RISC-style instructions require multiple (sometimes many) clock cycles to complete, such as mul/div, floating point math

Which seems like stuff you want support for, but this is seemingly arguing against?

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#127

Earlier quoted context omitted.

>and more about "don't add any assembly programmer conveniences or other such cleverness, rely on compilers instead of frontend silicon when possible" What are the advantages of that?

complexity that the compiler removes doesn't have to be handled by the CPU at runtime

Sure but that's not necessarily at odds with "programmer conveniences or other such cleverness" is it?

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#129
post #122

Earlier quoted context omitted.

That's not exactly it; quite a few RISC-style instructions require multiple (sometimes many) clock cycles to complete, such as mul/div, floating point math, and branching instructions can often take more than one clock cycle as well, and then once you throw in pipelining, caches, MMUs, atomics... "one clock cycle" doesn't really mean a lot. Especially since more advanced CPUs will ideally retire multiple instructions…

>quite a few RISC-style instructions require multiple (sometimes many) clock cycles to complete, such as mul/div, floating point math Which seems like stuff you want support for, but this is seemingly arguing against?

It seems contradictory because the "one clock per instruction" is mostly a misconception, at least with respect to anything even remotely modern.

https://retrocomputing.stackexchange.com/a/14509

Re: Box64 and RISC-V in 2024: What It Takes to Run the Witcher 3 on RISC-V

#130
post #53

Earlier quoted context omitted.

> Fast big cores should just stick to fixed size instrs for faster decode. How much faster, though? RISC-V decode is not crazy like x86, you only need to look at the first byte to know how long the instruction is (the first two bits if you limit yourself to 16 and 32-bit instructions, 5 bits if you support 48-bits instructions, 6 bits if you support 64-bits instructions). Which means, the serial part of the decoder i…

Frankly, there is no advantage to compressed instructions in a high performance CPU core as a misaligned instruction can span a memory page boundary, which will generate a memory fault, potentially a TLB flush, and, if the memory page is not resident in memory, will require an I/O operation. Which is much worse than crossing a cache line. It is a double whammy when both occur simultaneously. One suggested solution ha…

Page crossing affects a minuscule amount of cases - with 4096B pages and 100% non-compressed instructions (but still somehow 50% of the time misaligned), it affects only one in 2048 instructions.

The possibility of I/O is in no way exclusive to compressed instructions. If the page-crossing instruction was padded, the second page would need to be faulted in required anyway. All that matters is number of pages of code needed for the piece of code, which is simply just code size.

The only case that actually has a chance of mattering simply is just crossing cachelines.

And I would imagine high-performance cores would have some internal instruction buffer anyway, for doing cross-fetch-block instruction fusion and whatnot.

Post reply on HN