The Totally Unscientific Code Density Competition!

The EightThirtyTwo ISA – Part 22 – 2020-05-04

What better way to celebrate Star Wars Day than with a multi-CPU code density shoot-out?! (Well, OK, most people can probably name a dozen better ways without even trying – but this is how I’m choosing to spend it!)

I was curious to know just how well the code density of EightThirtyTwo code generated by the VBCC backend stacks up against other architectures, so I compiled a fixed codebase, namely the OSD control module from one of the many Minimig variants, targetting 832, m68k, MIPS, OpenRISC, RISC-V ARM, and even i386 and x86-64. The results make for interesting reading…

Firstly, I should point out that while the 832 code is compiled with VBCC, I used GCC for all the other target architectures. In all cases I used the -Os optimisation setting, the -ffunction-sections and -fdata-sections flags when compiling, and the -Wl,–gc-sections and -Wl,–relax flags when linking. This ensures that no ‘dead’ code is incorporated into the final binaries, and that reference are optimised to their smallest possible form at link time. These settings best mimic what the 832 assembler and linker do.

So firstly, the code in question is a bunch of C code which bangs hardware registers, handles reading from SD card and interfacing with the on-screen menu system from Minimig. It takes very little porting from one CPU to another, so while I haven’t actually run the compiled code on the various CPUs, I have no reason to believe that it wouldn’t work, or is in any way incomplete.

It’s entirely possible that compiler settings could be tuned to improve the results for any of these architectures – I haven’t attempted to do that. Where an architecture has various different versions available, I’ve simply used the one that best suits whichever soft CPU I would choose if I were to use that architecture

The sizes, in bytes, produced for the various architectures were as follows (in descending order of size):

  • OpenRISC – 81376
  • MIPS (f32c) – 71356
  • RISC-V – 69936
  • ZPU – 68868
  • ARM – 67952
  • X86-64 – 66112
  • m68k (68000) – 65760
  • i386 – 64080
  • 832 – 63599

So, that’s a pretty clear victory for EightThirtyTwo, yes?

Well… yes and no. Given that only one CPU on the list has a smaller logic footprint (ZPU), I’m pretty pleased with that result – and I’m actually pleasantly surprised to be beating i386 here, given that there’s been 30-odd years’ experience in optmizing compilers for that architecture. However, what I haven’t taken into account yet are compressed architectures:

MIPS, RISC-V and ARM all have subsets of their instruction sets which can be expressed in 16-bit rather than 32-bit words – and the file sizes when built for those architectures are impressively small:

  • RISC-V compressed – 57780
  • MIPS16 – 54192
  • ARM Thumb – 51436

So ARM Thumb is clearly the winner here, by a significant margin! Nonetheless, I don’t have the option of using thumb code in my FPGA projects – nor even MIPS16. I could, if I wished, use RISC-V compressed (with picorv32), and the other soft CPUs I could easily deploy are m68k (TG68), ARM (Amber), OpenRISC (or1200 or mor1kx), MIPS (f32c), ZPU (ZPUFlex) or – of course – 832.

Leave a Reply

Your email address will not be published. Required fields are marked *