Looks very cool; the idea of having "big" and "little" processors on the same SoC is interesting. I wondering if this is a big win vs. just having a "big" processor that is frequently put into idle mode when not needed.
As a side note, does anyone else find the ARM naming conventions totally impossible to follow? I look at the list of ARM models (http://en.wikipedia.org/wiki/List_of_ARM_microprocessor_core...) and have no idea where to begin. The family/architecture/core scheme means you can have a single chip that is an ARM11 family, ARMv6 architecture, ARM1136JF-S core. How do people make sense of this?
As someone who's writing a library that I want to be supported across all (or most) ARM cores, I don't have any idea how many different chips I'd need to test against to get a representative sample. There are so many optional features (NEON, Thumb, Thumb-2, VFP, etc) that seems to be supported in various combinations across the different models. It's like a maze and I never have any idea how a new model I read about fits in.
One good thing about 64-bit ARM is that there are no optional extensions (yet...) Floating-point and SIMD support are both required.
As for your library, ignore CPU models to start with. Instead, look at the ARM architecture reference manual for a given revision; it will say which instructions are supported and which extensions are optional. Also the quick reference [1] which has a good summary of when various core instructions were added. Then test for the instructions you actually care about.
You can safely ignore Thumb; it's an alternate encoding with tradeoffs that made sense nearly two decades ago but not anymore. You can also mostly ignore Thumb-2; there are processors that only support Thumb-2 but they also lack MMUs. Thumb-2 added some additional ARM instructions that can be useful, however.
So essentially, (with each revision including the prior)
Thumb was optional in v4 and v5, and mandatory in v6. VFP was optional as of ARMv6, NEON optional as of ARMv7. NEON mandates VFP. Revisions of VFP and NEON aren't terribly important, except that VFPv3 (but not VFPv3-d16) gets 32 registers.
As for chip to care about, ARMv6 + VFP (ARM1176jzf-s), ARMv7-A + VFPv3-d16 (Tegra 2), and ARMv7-A + NEON are by far the most common for general purpose stuff. If you want to get old-school, test a SheevaPlug for ARMv5E and an old PDA for ARMv4, though I'd not worry too much about ARMv4 (llvm for instance requires a baseline of ARMv5E last I checked.)
Does your library have to be a single compiled binary across all these variants? If so, good luck...
Otherwise, hopefully, a compiler takes care of most of the mess for you and gets you the best it can on the platform you're targeting. You might need to check that things would run on a variety of configurations - for instance hardfloat and softfloat do indeed have very different performance profiles when it comes to floats. Thumb shouldn't bother you too much as an application programmer (unless I'm very much mistaken) because it's just another instruction set for a compiler to target.
Errr....
You can get into all sorts of complications when actually looking at the platform ABIs. Debian, for instance, seem to have something of a lowest-common-denominator approach that targets features present everywhere. Which is then why someone had to rebuild it to get decent FP performance out of the Raspberry Pi which had hard-float...
Part of the complexity is that ARM is a licensed architecture. Some companies license the design of the whole core, some incorporate their own stuff and some just license the instruction set and do their own stuff otherwise.
What do you mean 'supported across all (or most) ARM cores'? Because that's huge and varies massively. There are the sub-100MHz embedded devices I happen to be working on at the moment (which may be running any of a load of different OSs), there are ARM cores embedded in all sorts of controllers where I wouldn't think you'd want to run, then there's the multi-core multi-GHz stuff from the likes of Samsung, Qualcomm and Marvell...
" Debian, for instance, seem to have something of a lowest-common-denominator approach that targets features present everywhere."
Debian actually has three ARM ports in progress.
ArmEabiPort - newer port using the "new" ABI (EABI), supported on ARM v4t and higher. First released with 5.0 (Lenny). GNU Triplet: arm-linux-gnueabi
ArmHardFloatPort - the latest 32-bit port, using the hard-float version of the "new" ABI (EABI), targetting ARM v7 and up. To be released with 7.0 (Wheezy). GNU Triplet: arm-linux-gnueabihf
Arm64Port - the latest port, for the 64-bit ARMv8 architecture. Likely to be released with 8.0 (Jessie). GNU Triplet: aarch64-linux-gnu
> Does your library have to be a single compiled binary across all these variants?
No no, not that. :)
As Matt mentioned my work does include JIT compilers, so I'm curious to know how many instruction variants I'd have to support. But I also want to simply test that my plain C code (ie. the interpreted, slow paths) doesn't make any platform-specific assumptions that break on some processors.
> What do you mean 'supported across all (or most) ARM cores'?
My intention is that anyone can compile my library out-of-the-box and have it just work, unless their CPU has a fundamental limitation that I can't support. So far the only such limitation I want to concede is that I require at least a 32-bit CPU (for one, my program's code and data will only barely fit in 64k of RAM, and wouldn't leave much space for anything else).
I know that some of haberman's libraries (like upb) include JIT compilers. In those cases you can't just rely on the compiler to take care of instruction set differences. (I'm on the mobile Firefox team, and we run into similar issues targeting our JavaScript engine to different ARM flavors.)
Then that very well could turn out to be a complete nightmare!
Yes, if you're in the business of writing compilers - traditional, JIT or otherwise - then you're going to hit all sorts of issues with this stuff, and rapidly head off beyond the realms in which I have anything useful to say :)
Well, in regards to the first question generally a processor's performance is proportional to the sqaure root of it's area at a given frequency and voltage, and it's active power use and leakage are both proportional to it's area. So yes, a smaller core will be able to accomplish the same task for less energy even though it takes longer.
Now it used to be that processors power budget was dominated by active power and the solution was to scale clockspeeds and voltage levels. As we move to smaller process nodes it's more about leakage power, which only goes away when you power down the core meaning that now race to idle is a better choice. But that's tangential to the bigger/smaller core issue.
As I understand it, incorrect branch prediction becomes significantly more expensive (power-/time-wise) as pipeline length increases, so getting the prediction right and being able to correct quickly is quite important.
Tegra 3 already has this big/little architecture, but using the same core design for all cores, the difference being that the "little" core is clocked lower and fabbed with a special low-power process. I imagine using two different core designs would be even more effective.
As a side note, does anyone else find the ARM naming conventions totally impossible to follow? I look at the list of ARM models (http://en.wikipedia.org/wiki/List_of_ARM_microprocessor_core...) and have no idea where to begin. The family/architecture/core scheme means you can have a single chip that is an ARM11 family, ARMv6 architecture, ARM1136JF-S core. How do people make sense of this?
As someone who's writing a library that I want to be supported across all (or most) ARM cores, I don't have any idea how many different chips I'd need to test against to get a representative sample. There are so many optional features (NEON, Thumb, Thumb-2, VFP, etc) that seems to be supported in various combinations across the different models. It's like a maze and I never have any idea how a new model I read about fits in.