virtual CPU: Difference between revisions

From SEGGER Knowledge Base
Jump to navigation Jump to search
mNo edit summary
Line 10: Line 10:
Steve Wozniak claims to have saved about 1KB of program code (out of 5KB) by implementing a part of his basic interpreter in SWEET16, without noticeable performance degradation. Assuming that he "virtualized" half of the program code, that means a 40% code size reduction of the part virtualized. With the 300bytes required for the executor, he still saved around 724 bytes of program size (assuming the SWEET16 executor was only used for this purpose). A similar thing can be achieved these days with a virtual CPU on a RISC-V, with code size savings of about 30%.
Steve Wozniak claims to have saved about 1KB of program code (out of 5KB) by implementing a part of his basic interpreter in SWEET16, without noticeable performance degradation. Assuming that he "virtualized" half of the program code, that means a 40% code size reduction of the part virtualized. With the 300bytes required for the executor, he still saved around 724 bytes of program size (assuming the SWEET16 executor was only used for this purpose). A similar thing can be achieved these days with a virtual CPU on a RISC-V, with code size savings of about 30%.
== Examples==
== Examples==
* [[SWEET16]] - One of, if not the first implementation of a virtual CPU. Implemented a 16-bit CPU on a 6502 on an Apple II by Steve Wozniak.
* [[Sweet 16 |SWEET16]] - One of, if not the first implementation of a virtual CPU. Implemented a 16-bit CPU on a 6502 on an Apple II by Steve Wozniak.
* SEGGER [[S32E]] - SEGGER's generic virtual 32-bit CPU. Extremely efficient and very high code density. Used in many SEGGER products such as the Flasher family of [[In-system programming | in-system programmers]], J-Link debug probes and also in emApps, which makes this functionality available to 3rd parties.
* SEGGER [[S32E]] - SEGGER's generic virtual 32-bit CPU. Extremely efficient and very high code density. Used in many SEGGER products such as the Flasher family of [[In-system programming | in-system programmers]], J-Link debug probes and also in emApps, which makes this functionality available to 3rd parties.

Revision as of 16:08, 7 September 2025

A virtual CPU is a CPU implemented in software. It is typically executed by an executor (a sort of simulator for the CPU) which runs on a real (host) CPU.

Overview

A virtual CPU is in many respects very similar to a real, physical CPU. A physical CPU runs directly on hardware, in either a soft core or hard core. A virtual CPU also has a defined instruction set (ISA), but is not implemented in hardware, but instead executed in software. The execution is typically by an executor, which loads the instructions and executes it in software, meaning that it simulates the CPUs. However, there is also the option to translate the instruction stream of the virtual CPU into native code, so basically compile on the host, before executing it.

Performance

Performance of the virtual CPU obviously depends on many factors, such as the ISA of the virtual CPU and the implementation of the executor. For well optimized executors, a factor of 10-20 is realistic, meaning that functionality implemented on the host (native CPU) is about 10-20 times as fast as implementation on the virtual CPU. While this sounds like a lot, it is normally not a problem when implementing compute intensive functionality on the host itself. Especially for systems in which the virtual CPU is more powerful than the underlying host the performance factor can be better than 10 since fewer instructions are required. This applies to SWEET16, which implements a virtual 16-bit CPU on the 8-bit 6502 CPU, but also to systems like S32E, especially when running on a RISC-V host.

Code density

Code density of virtual CPU obviously depends on the ISA of the virtual CPU. There is a trade-off between the size of the executor and the code density of the virtual CPU: The more instructions are available, the larger the executor. As a general rule, code density of the virtual CPU is usually higher than that of the host CPU, as virtual CPUs are typically optimized to use fewer instructions. Steve Wozniak claims to have saved about 1KB of program code (out of 5KB) by implementing a part of his basic interpreter in SWEET16, without noticeable performance degradation. Assuming that he "virtualized" half of the program code, that means a 40% code size reduction of the part virtualized. With the 300bytes required for the executor, he still saved around 724 bytes of program size (assuming the SWEET16 executor was only used for this purpose). A similar thing can be achieved these days with a virtual CPU on a RISC-V, with code size savings of about 30%.

Examples

  • SWEET16 - One of, if not the first implementation of a virtual CPU. Implemented a 16-bit CPU on a 6502 on an Apple II by Steve Wozniak.
  • SEGGER S32E - SEGGER's generic virtual 32-bit CPU. Extremely efficient and very high code density. Used in many SEGGER products such as the Flasher family of in-system programmers, J-Link debug probes and also in emApps, which makes this functionality available to 3rd parties.