Page 1 of 2

Need explanations about Floating Point Unit

Posted: Mon Dec 09, 2013 12:45 pm
by Fede
Hi all,

I would like to use the fpu on stm32f4 Discovery board, to do that I have to set (USE_FPU = yes) in the makefile and that's all?

so whether I write: float x = 2.0f * 5.0f; this will be calculated with fpu?

I noticed these two rows in the bottom of makefile:

Code: Select all

ifeq ($(USE_FPU),yes)
  USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
  DDEFS += -DCORTEX_USE_FPU=TRUE


It means that FPU is in fact a software fpu? if is true, how can i use hardware fpu? -mfloat-abi=hard?
I'm confused... sorry
Thank you in advance

PS: ( I use gcc with -lm on ubuntu )

Re: Need explanations about Floating Point Unit

Posted: Mon Dec 09, 2013 1:30 pm
by Giovanni
Hi,

The Cortex-M4 FPU only handles single precision floats (32 bits), double precision is handled in software by libraries.

Fede wrote:so whether I write: float x = 2.0f * 5.0f; this will be calculated with fpu?


No, it is double precision and the multiplication would be performed at compile time anyway being a constant expression.

Giovanni

Re: Need explanations about Floating Point Unit

Posted: Mon Dec 09, 2013 2:25 pm
by Fede
Thanks Giovanni, but i can't understand why it is a double precision...

According to: http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/application_note/DM00047230.pdf

3.5.1 Arithmetic instructions [pag. 14]
The FPU offers arithmetic instructions for:
● Absolute value (1 cycle)
● Negate of a float or of multiple floats (1 cycle)
● Addition (1 cycle)
● Subtraction (1 cycle)
● Multiply, multiply accumulate/subtract, multiply accumulate/subtract then negate (3 cycles)
● Divide (14 cycles)
● Square root (14 cycles)
All the MAC operations can be standard or fused (rounding done at the end of the MAC for a
better accuracy).
3.5.2 FPU compare & convert instructions
The FPU has compare instructions (1 cycle) and a convert instruction (1 cycle).
Conversion can be done between integer, fixed point, half precision and float

Code: Select all

float x=1.2f;
float y=1.3f;
float z=x*y;  // (3 cycles) ?


If it is wrong yet, what is the correct way?

Re: Need explanations about Floating Point Unit

Posted: Mon Dec 09, 2013 2:39 pm
by Giovanni
You should look at the generated code. The compiler is smart enough to understand those lines are a constant expression even if you declare 3 variables.

Giovanni

Re: Need explanations about Floating Point Unit

Posted: Tue Dec 10, 2013 4:51 pm
by pito
The FPU inside STM32F4 is a single precision fpu (32bit). Double precision calculations (64bit float number) are provided in software.
To avoid the compiler optimizes the calculation off, you may try:

Code: Select all

..
// prints out a double precision number in hex
void print64x( double x ) {
   const char* p;
   int j;
   p = (char *) &x;   
   for( j=0; j< sizeof(x); j++) {
      printf("%02X", p[(sizeof(x)-1)-j]&0xFF);
   }
}
// prints out a single precision number in hex
void print32x( float x ) {
   const char* p;
   int j;
   p = (char *) &x;   
   for( j=0; j< sizeof(x); j++) {
      printf("%02X", p[(sizeof(x)-1)-j]&0xFF);
   }
}
...
volatile double x;
volatile double y;
volatile double z;

for (int i = 0; i<=10; i++) {
x = 3.1415;
y = x * i;
z = x + y;
printf("z  = %f\n", z);
printf("z (single HEX) = "); print32x( z ); printf("\n");
printf("z (double HEX) = "); print64x( z ); printf("\n");
..
}

Re: Need explanations about Floating Point Unit

Posted: Thu Dec 12, 2013 4:13 pm
by kenyee
I think what Fede is saying is if he defines all his variables to be the C type "float" instead of "double", will it use the Cortex's single precision FPU?

I'm curious myself though I haven't tried it yet (still waiting on an STM32F429 Discovery board)...

Re: Need explanations about Floating Point Unit

Posted: Thu Dec 12, 2013 5:04 pm
by Giovanni
I think you have to use "single" in order to use the FPU.

Giovanni

Re: Need explanations about Floating Point Unit

Posted: Sun Feb 02, 2014 3:54 pm
by pito
I've spent few hours trying to understand the fp in CM4 chibios too.. :) Still coping with it however. Here is a short demo (STM32F4 Discovery demo based), one may try:

Code: Select all

// Simple math test
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include <math.h>

#define serial2 (BaseSequentialStream*)&SD2

int main(void) {

  halInit();
  chSysInit();

  sdStart(&SD2, NULL);
  palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
  palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));


  while (TRUE) {

   volatile float q32, p32;
   int i;
   systime_t timestart, timeelapsed;

    chprintf (serial2,  " THIS IS THE START \r\n");
    p32 = 3.1415926535897932384626433832795f;
    timestart = chTimeNow();
    for (i=1;i<=1000;i++) {
        // 9 degree
        q32 = 9.000f;
        // Convert to radians
        q32 = q32 * p32 / 180.0f;
        // Make the test
        q32= asin(acos(atan(tan(cos(sin(q32))))));
        // Convert to degree
        q32 = q32 * 180.0f / p32;
          }
    timeelapsed = chTimeNow() - timestart;
    chprintf(serial2, " Elapsed time 1000x : %d millis\r\n", timeelapsed);
    chprintf(serial2, " Elapsed time : %f millis\r\n", timeelapsed/1000.0f);
    chprintf (serial2, " Result : %f \r\n", q32);
    chprintf (serial2, " THIS IS THE END \r\n \r\n");

    chThdSleepMilliseconds(100);
  }
}


I did following int Makefile:

Code: Select all

..
# Enables the use of FPU on Cortex-M4.
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FPU),)
  USE_FPU = yes
endif

# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FWLIB),)
  USE_FWLIB = no
endif
..
# Start of user section
#

# List all user C define here, like -D_DEBUG=1
UDEFS = -DCHPRINTF_USE_FLOAT=TRUE  -DUSE_FPU=TRUE
..
# List all user libraries here
ULIBS = -lm
..

It seems to me the FPU is not activated however. Getting results around 114ms with -DUSE_FPU=FALSE and the same with TRUE.. :?

PS: It would be great to have the floating point printf and FPU enabling supported in chconf.h by 2 simple defines, for example..

Re: Need explanations about Floating Point Unit

Posted: Sun Feb 02, 2014 3:58 pm
by Giovanni
The FPU handles single floats only, if you use double float the calculation is done in SW. You can see the difference in context switch time, when the FPU is enabled scores are much lower because the overhead.

Giovanni

Re: Need explanations about Floating Point Unit

Posted: Sun Feb 02, 2014 4:05 pm
by pito
Giovanni,
I am using single precision floating point types (32bit) supported by the FPU.

Code: Select all

..
volatile float q32, p32;
..

There is no other way to define a single precision float..

It might be, that there is somewhere a compiler directive defining the single precision float shall be handled as double, then, of course, the compiler does it in sw (as it will handle the single precision as the double).

Code: Select all

-fshort-double
    Use the same size for double as for float.


But the source above must be compiled with FPU support when everything is ok.