When emulating Nintendo DS, are ARM-based devices at an advantage over x86?

Recently I have been emulating the Nintendo DS, both on my x86 Windows/macOS machine and on my ARM device (currently Android, but I would also like to try on a Linux desktop with ARM CPU.)

I find that I get much better performance on the ARM device.

Has this got anything to do with architecture? I know that the DS also has an ARM processor. Does this make the emulation easier on ARM devices? Sort of something in between emulation and virtualisation? Or is it most likely due to some other factor?


Solution 1:

I find that I get much better performance on the ARM device.

Has this got anything to do with architecture?

Yes, it has.

Without trying to bore you with technical details, running code is a lot like following a cook book. Meanwhile, code that was written for a different platform is a lot like a cook book written in a foreign language.

Sometimes, translating an instruction from one language to another is simple. Sometimes, what can be expressed in a single word in one language, requires a lecture on philosophy in another. And sometimes, you might need cooking tools that are incredibly common overseas, but not where you live.

The closer the cook book's language is to your own, the easier it will be to follow. That is why an ARM CPU achieves better performance in emulating another ARM CPU, than a CPU of a completely different architecture.

Sort of something in between emulation and virtualisation?

You could put it that way, though technically it is still 100% emulation, 0% virtualisation.

Virtualisation is when the code can be executed natively (directly) on the CPU. Even on an ARM CPU, you can't simply run NDS code natively. Some of the reasons include:

  • Non-standard extensions: this is very common in consoles. Since you don't need to be compatible to a potentially unlimited number of hardware configurations, you can easily define a set of capabilities you need. If the ARM architecture doesn't offer it, you can just add it in. Instructions that make use of those obviously won't run on any other ARM CPU.
  • Bugs and undefined behavior: Sometimes there are bugs in the CPU, which you won't find anywhere else. Sometimes there are developers who are either knowingly or unknowingly relying on the weird behavior caused by the bug. The same applies to undefined behavior.
  • Timings: This is pretty common among consoles. Since the hardware (and performance) always stays the same, developers assume that one second will always last 67 Million clock cycles. Obviously, when the game is suddenly running on a 2 GHz CPU (2 Billion cycles per second), the game could quickly become unplayable. Imagine playing a game at 30x the normal speed...

To say nothing of the things unrelated to the CPU, which still need emulating.

Or is it most likely due to some other factor?

Not in this case, but it's also possible.

In theory you could design a CPU that has all the same capabilities, bugs, and quirks as the original NDS CPU, but uses a completely different architecture. If that CPU also happens to be faster and more efficient than a regular ARM CPU, you would end up with a non-ARM CPU that can emulate the NDS CPU better than a real ARM CPU ever could.

But that's purely theory. In reality, it'd probably be easier to include an FPGA (Field Programmable Gate Array), and program it to be a perfect replica of the NDS CPU. In that case, we wouldn't even need to emulate anything anymore (unless we want convenience features like graphics upscaling, fast forwarding, etc.), except maybe some of the NDS' unique features, like detecting whether the lid has been closed.