Teensy 3.5: FPU limited to 8-bit precision and ADC speeds?

Status
Not open for further replies.

dosox

New member
Teensy 3.5: FPU limited to 32-bit / ADC speeds?

// update: please note that the title was misleading (I meant 32-bit) and I mixed up two topics (both were on my mind but the distinction was not as clear as I intended it to be). Fixed the title - thanks everyone for the really helpful answers!

Hey everyone,
I just received my Teensy 3.5 and did a few checks. What I did notice right away is that the FPU seems to work only on float variables. This is what a simple check gave me (Arduinos left here for comparison):

Code:
Time for floating-point operations:
in seconds per million / ms per thousand / ns per operation

    Uno (float)   Due (float)  Due (double)  T_3.5 (float)  T_3.5 (double)
+          9.09          1.26          1.87           0.04            1.13
-          9.19          1.26          1.88           0.04            1.13
*          9.69          0.80          1.70           0.04            0.83
/         30.82          2.74         10.62           0.12            5.55

Time for ADC (analogRead), same units as above:
    Uno (10bit)   Due (10bit)   Due (12bit)  T_3.5 (12bit)  T_3.5 (13bit)
aread    112.0            4.3           4.1            8.4           20.2

My question is simple: I'm using standard Arduino code (e.g. analogRead()) - am I missing something (like one of the libraries for the Teensy) that will speed things up? (The speeds I'm currently achieving are fine for my current use-case, but it would be good to know)

Note: The code I'm using is linked in my blogpost with speed-comparisons for Arduino Uno/Due and Teensy 3.5 boards or here.
 
Last edited:
The FPU is 32 Bit. There is no 8-Bit float format. I dont' understand your question regarding ADC.
Edit: The FPU does not speed up ADC. That are completely different things (?!?)
 
Last edited:
The float data type is 32-bits using the standard IEEE 754 binary 32-bit format: https://en.wikipedia.org/wiki/Single-precision_floating-point_format:
  • 1 bit for the sign
  • 8 bits for exponent
  • 23 bits for the mantissa (note, in IEEE format, for normal numbers, you get an extra implicit bit, as the mantissa is shifted so the first bit is always one, and the remaining 23 bits are stored in the floating point value).

Quoting from from above document:
All integers with 6 or fewer significant decimal digits can be converted to an IEEE 754 floating-point value without loss of precision, some integers up to 9 significant decimal digits can be converted to an IEEE 754 floating-point value without loss of precision, but no more than 9 significant decimal digits can be stored. As an example, the 32-bit integer 2,147,483,647 converts to 2,147,483,650 in IEEE 754 form.

This means anything that analogRead returns (normally 0..1023, but you can have it return 0..65535, but the bottom 2-3 bits are likely random in 16-bit mode) will fit in a float value.

Teensy has a double type which uses IEEE 754 64-bit encoding (https://en.wikipedia.org/wiki/Double-precision_floating-point_format). In all Teensies, double is emulated in software. In the Teensy 3.5 and 3.6, float is done in hardware. In the Teensy 3.2, 3.1, 3.0, and LC, float is emulated in software.

If you use the math functions (sin, cos, log, etc.), you want to use the float versions of these functions (sinf, cosf, logf). Otherwise, the compiler/library must convert the value to double, do the math function in emulated 64-bit arithmetic, and then convert the result back into 32-bit.

Also note, Paul puts the option -fsingle-precision-constant on in Teensy builds. This has the effect that for calculations done in float, it does not force the calculation to be done in 64-bit, but on the other hand, if you really need 64-bit floating point, the bottom 32-bits of the mantissa will be truncated. The usual work around is to use a 'L' suffix, which makes the constant a long double constant, which then converts down into normal double without loss of precision (on Arm systems, long double is the same as double, but on other systems like the x86 or PowerPC, long double gives more precision).

Note that AVR based Arduinos (Uno, Leonardo, etc.) and the Teensy 2.0/2.0++ do not implement double as 64-bit, but instead double uses the same encoding as float. In the AVR cpus, floating point is always emulated.
 
Edit: The FPU does not speed up ADC. That are completely different things (?!?)

Shure, (the OP mixed up two different observations) but if you run his test program (following the links) with different analogue resolutions you will see that the MCU is slower for higher resolutions (makes sense for an SAR - type ADC)

I get for 1 T3.6 running at 180 MHz
Code:
 5.60 s for 1 Mio ADC ops @ analogReadResolution(8)
 6.62 s for 1 Mio ADC ops @ analogReadResolution(10)
 8.30 s for 1 Mio ADC ops @ analogReadResolution(12)
17.81 s for 1 Mio ADC ops @ analogReadResolution(13)
17.81 s for 1 Mio ADC ops @ analogReadResolution(14)
17.81 s for 1 Mio ADC ops @ analogReadResolution(16)
The jump after 12 bit analogue resolution and drawing the curve, which not linear, indicates that for resolutions 13-16 bit ADC always converts to 16 bit
 
Hey everyone, thank you so much for the patience and the helpful replies.

I'm sorry about my slightly confusing post (I updated it to avoid further confusion). Also, I did read your replies quite carefully and learned a lot from them (so I'm glad I did ask, but I'm sorry for the confusion).

The jump after 12 bit analogue resolution and drawing the curve, which not linear, indicates that for resolutions 13-16 bit ADC always converts to 16 bit
Sidenote: I believe I read somewhere that the usable ADC range / precision is limeted to 13 bit.
 
Last edited:
Sidenote: I believe I read somewhere that the usable ADC range / precision is limeted to 13 bit.

Yes, but you should also understand 13 bits is a best case scenario, where the signal is from a low impedance source.

In practice, good analog circuit design requires a lot of expertise and difficult design work. Tough analog problems like ground loops, power supply noise coupling, 1/f noise from high impedances, and many others issues are common with *any* microcontroller-based design.

13 bits is really quite an incredible level of analog precision. I know in these modern times people are used to seeing specs about 24 bit audio, but much like the notion that Teensy could do more than 13 bits, the idea of 24 actual bits with audio is nothing more than wishful thinking (or deceptive marketing).
 
Status
Not open for further replies.
Back
Top