Need explanations about Floating Point Unit

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

User avatar
Fede
Posts: 37
Joined: Thu Nov 08, 2012 8:30 pm
Location: Milano

Need explanations about Floating Point Unit

Postby Fede » Mon Dec 09, 2013 12:45 pm

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 )

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Need explanations about Floating Point Unit

Postby Giovanni » Mon Dec 09, 2013 1:30 pm

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

User avatar
Fede
Posts: 37
Joined: Thu Nov 08, 2012 8:30 pm
Location: Milano

Re: Need explanations about Floating Point Unit

Postby Fede » Mon Dec 09, 2013 2:25 pm

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?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Need explanations about Floating Point Unit

Postby Giovanni » Mon Dec 09, 2013 2:39 pm

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

pito
Posts: 199
Joined: Sun Nov 06, 2011 3:54 pm

Re: Need explanations about Floating Point Unit

Postby pito » Tue Dec 10, 2013 4:51 pm

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");
..
}

kenyee
Posts: 14
Joined: Fri Sep 20, 2013 8:27 pm

Re: Need explanations about Floating Point Unit

Postby kenyee » Thu Dec 12, 2013 4:13 pm

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)...

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Need explanations about Floating Point Unit

Postby Giovanni » Thu Dec 12, 2013 5:04 pm

I think you have to use "single" in order to use the FPU.

Giovanni

pito
Posts: 199
Joined: Sun Nov 06, 2011 3:54 pm

Re: Need explanations about Floating Point Unit

Postby pito » Sun Feb 02, 2014 3:54 pm

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..
Last edited by pito on Sun Feb 02, 2014 5:15 pm, edited 1 time in total.

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Need explanations about Floating Point Unit

Postby Giovanni » Sun Feb 02, 2014 3:58 pm

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

pito
Posts: 199
Joined: Sun Nov 06, 2011 3:54 pm

Re: Need explanations about Floating Point Unit

Postby pito » Sun Feb 02, 2014 4:05 pm

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.
Last edited by pito on Sun Feb 02, 2014 4:16 pm, edited 1 time in total.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 37 guests