Live data from Hacker News

Why is Rosetta 2 fast?

dougallj.wordpress.com

341–350 of 367 posts

Re: Why is Rosetta 2 fast?

#341
post #304

Earlier quoted context omitted.

Static compilers usually don't have to make such a tradeoff, though. They are free to spend arbitrarily long amounts of time optimizing all branches. And they often do exactly that. Static + LTO w/ PGO is pretty much the practical ideal. JITs don't offer much until you start adding dynamically loaded code where LTO just isn't possible anymore.

If your hardware is designed to allow very lightweight profiling and tracing, then static + LTO w/ PGO can still be improved by runtime re-optimization. If designed properly, the runtime overhead can be brought arbitrarily low by increasing the sampling period.

Are you speaking in theoreticals or can you point to any actual example of what you're describing? Usually for a JIT to work the source binary has to be unoptimized to begin with, otherwise information is lost that the JIT needs.

So What language/runtime out there ships unoptimized bytecode, an optimized precompiled static + LTO w/ PGO, and can re-optimize with runtime gathered information via a JIT?

Heck, what language/runtime is even designed around being performance-focused with a JIT to deliver even more performance in the first place? Pretty much ever JIT'd language makes trade-offs that sacrifice up-front performance and later hopes the JIT can claw some of it back. maybe this is kinda WASM-ish territory, although it then sacrifices up-front performance for security and hopes the JIT can claw it back.

Re: Why is Rosetta 2 fast?

#342
A lot of the simplicity of this approach relies on the x86 registers being able to be directly mapped to arm registers. This seems to be possible for most x86 registers, even simd registers. Although, I think this falls over for avx512, which is supported on the Mac pro. Arm neon has 32 128 bit registers - avx512 supports 32 512 bit registers and dedicated predicate registers. What do they do? Back to jit mode?

Re: Why is Rosetta 2 fast?

#343

A lot of the simplicity of this approach relies on the x86 registers being able to be directly mapped to arm registers. This seems to be possible for most x86 registers, even simd registers. Although, I think this falls over for avx512, which is supported on the Mac pro. Arm neon has 32 128 bit registers - avx512 supports 32 512 bit registers and dedicated predicate registers. What do they do? Back to jit mode?

oh, they don't support avx:

https://developer.apple.com/documentation/apple-silicon/abou...

Re: Why is Rosetta 2 fast?

#344
post #99
post #90

Earlier quoted context omitted.

I have a single counter-example. Mailplane, a Gmail SSB. It's Intel including its JS engine, making the Gmail UI too sluggish to use. I've fallen back to using Fluid, an ancient and also Intel-specific SSB, but its web content runs in a separate WebKit ARM process so it's plenty fast. I've emailed the Mailplane author but they wont release an Universal version of the app since they've EOL'd Mailplane. I have yet to f…

For what it's worth, I use Mailplane on an M1 MacBook Air (8GB) with 2 Gmail tabs and a calendar tab without noticeable issues. Unfortunately the developers weren't able to get Google to work with them on a policy change that impacted the app [0] [1] and so gave up and have moved on to a new and completely different customer support service. [0] https://developers.googleblog.com/2020/08/guidance-for-our-e... [1] http…

I wonder what's different about my setup. I've tried deleting and re-installing Mailplane and tried it on two different M1s (my personal MBA and my work 16" MBP). On both, there is significant lag in the UI. Just using the j/k keys to move up/down the message list it takes like 500 ms for the selected row to change.

I use non-default Gmail UI settings. I'm still using the classic theme, dense settings, etc. I'll try again, because I'd really like to use Mailplane as long as it will survive.

I'm aware why Mailplane has been EOL'd. But the developer also claims he's trying to keep it alive as long as possible and he's released at least one version since that blog post, so I'd hoped he would be willing to release a universal build. I don't know anything about the internals of Mailplane but I guess it's a non-trivial amount of work to do so.

Re: Why is Rosetta 2 fast?

#345

Earlier quoted context omitted.

A lesser known bit of trivia about this is that IBM would go on to use Transitive's technology for the exact opposite of Rosetta -- x86 to PowerPC translation, in the form of "PowerVM Lx86", released that year (2008). It's very fascinating to me, since IBM appears to have extended the PowerPC spec with this application specifically in mind. Up until POWER10, the Power/PowerPC ISA specified an optional feature called…

In theory, PROT_SAO should be useful for qemu, and trivial to make patches implementing there. That's assuming the kernel actually sets it, though. The problem I encountered when I set out to do it a year or so ago, was that I couldn't find a good test case to fail without it...

The kernel definitely sets the WIMG bits at https://github.com/torvalds/linux/blob/master/arch/powerpc/m... (line 336, if HN removes it), though I've never been able to "make it work" either.

I used box64 as a test case, where I had a game that would run in emulation, but only if I pinned it to a single core. On ARM64, it also worked, as the JIT translator on box64 uses manually inserted memory fences to force strongly ordered access.

The game never worked correctly, even after I patched the kernel to mark every page on the system as SAO, and confirmed this worked by checking the set memory flags. This might be a mistake in my understanding of what SAO should do, though. (or another failure in box64 on ppc64le)

One thought I've had recently is perhaps it's like the recently discovered tagged memory extension and only worked in big endian? There's nothing in the docs to suggest this, but since the only test case was BE-only, maybe?

Re: Why is Rosetta 2 fast?

#346
post #264

Earlier quoted context omitted.

Ehh I had a 2013 MacBook pro back in 2013 with a 2560x1600 display. That's 227 dpi. A decade later, I think it's safe to say that anything smaller than that is extremely low-end in 2022. I agree it's kinda sad how few desktop monitors are high dpi. It gets even worse if you limit yourself to low latency monitors. Anyway I haven't used macos in a while so I'm not sure what you mean by Apple not supporting non-hidpi

The actual screen dimensions make a huge difference to whether or not a given DPI value is low or high end. My current monitor is 157 DPI and I can assure you it is not an extremely low end monitor at all. Unless your frame of reference is anything below $5k is low end or something.

Right, what I meant to say is that anything under 1600p is low end because it was already widely available in 2013.

Re: Why is Rosetta 2 fast?

#347

Earlier quoted context omitted.

One of the engineers I was working with on a project was from Transitive (the company that made QuickTransit which became Rosetta) found that their JIT based translator could not deliver significant performance increases for A->A outside of pathological cases, and it was very mature technology at the time. I think it's a hypothetical. The Mill Computing lectures talk about a variant of this, which is sort of equivale…

>"The Mill Computing lectures talk about a variant of this ..." Might you or someone else have a link those Mill Computing lectures?

Sure thing. I’m on mobile but the 2nd one was easy to find and is here -

https://youtu.be/QGw-cy0ylCc

Re: Why is Rosetta 2 fast?

#348
post #304

Earlier quoted context omitted.

If your hardware is designed to allow very lightweight profiling and tracing, then static + LTO w/ PGO can still be improved by runtime re-optimization. If designed properly, the runtime overhead can be brought arbitrarily low by increasing the sampling period.

Are you speaking in theoreticals or can you point to any actual example of what you're describing? Usually for a JIT to work the source binary has to be unoptimized to begin with, otherwise information is lost that the JIT needs. So What language/runtime out there ships unoptimized bytecode, an optimized precompiled static + LTO w/ PGO, and can re-optimize with runtime gathered information via a JIT? Heck, what langu…

The basic elements all exist.

As others have pointed out, HP's Dynamo managed to use runtime re-optimization to improve performance of many binaries without cooperation from the original compiler. Runtime optimization doesn't strictly require any of the information lost in optimized binary builds.

Last I checked, the Android Runtime would AoT-compile Dalvik bytecode at install time, and in the background re-optimize the binary based on profiling information. Though, I don't think it performs hot code replacement.

I'm not sure the latest with Oracle's Java AoT. Last I checked, Oracle's JVM wasn't able to inline or re-optimize AoT-compiled code through JIT'd code.

Some optimizations, such as loop unrolling make JIT'ing harder. However, strength reduction, loop-invariant code hoisting, etc. make the JIT's life easier. Back around 2005-2006, my employer was getting good mileage out of a Java bytecode optimizer. If your AoT and JIT are cooperating, the AoT can stuff any helpful metadata (type information, aliasing analysis, serialized control flow graph, etc.) into an auxiliary section of the binary.

I'd like to eventually write a C compiler that essentially compiles to old-school threaded code: arrays of pointers to basic blocks (strait-line code with a single entry point and one or more exit points). Function entry would just pass the array of basic blocks to a trampoline function that calls the first basic block. Each basic block would return and index into the function's array of basic blocks for the trampoline to call next. Function return would be signaled by a basic block returning -1 to the trampoline loop. A static single assignment representation of each extended basic block would be stashed in an auxiliary ELF section. On a regular system without the runtime optimizer, the only startup overhead would be due to bloated binary size. A wild guess at the performance overhead without the runtime optimizer would be in the 5% to 15% range. However, on a system with the ELF dynamic loader replaced with a runtime-optimizer, the runtime would set up a perf signal handler that would keep counters for identifying hotspots to trace. If the tracing conditions were met, the perf signal handler would walk back up the call stack to find the last occurrence of the address of the trampoline, and replace it with a version of the trampoline that in addition, stores the address of the next extended basic block to run. Once a trace loops back on itself or meets some other TBD criteria, the runtime would stitch together the SSA representations of the constituent extended basic blocks, and generate a new optimized basic block that's the inline of the components of the trace, and finally place the address of the new extended basic block in the correct place in the array of extended basic blocks, thus performing runtime code replacement. Anyway, that's my grand vision. I've taken the introductiory Stanford compilers course, and am slowly working my way forward, but I have a job and a young kid, so I'm not holding my breath.

Among other things, this allows for inlining of hot paths across dynamic library boundaries. It also improves code locality and should increase the percentage of not-taken branches in the hot path, which should help reduce problems with aliasing in the branch predictor.

Re: Why is Rosetta 2 fast?

#349
For history this was a major milestone in x86 binary translation, Digital FX!32:

https://www.usenix.org/legacy/publications/library/proceedin...

Some apps run faster than the fastest available x86 at the time, and sometimes significantly faster like the Byte benchmark cited above. Of course it helped that the chip was sugnificantly faster than leading x86 chips in the first place.

Re: Why is Rosetta 2 fast?

#350

Earlier quoted context omitted.

> To me it’s more of an argument towards distributing software in intermediate form (like Apple Bitcode) and compiling on install, tailoring for the current processor. This turns out to be quite difficult, especially if you're using bitcode as a compiler IL. You have to know what the right "intermediate" level is; if assumptions change too much under you then it's still too specific. And it means you can't use things…

> That's why bitcode is dead now. WebAssembly seems alive and well. I'm not sure how similar it is to java bitcode but its the same core idea. That said, WASM through v8 is ~3x slower than the same code compiled natively. (Some of this might be due to the lack of SIMD in wasm).

"Bitcode" is the name of a specific Xcode feature in this case, not a general comment.
Post reply on HN