Author Topic: Cortex M0+ math lib  (Read 14365 times)

0 Members and 1 Guest are viewing this topic.

Offline analitykTopic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: pl
Cortex M0+ math lib
« on: November 19, 2023, 03:17:12 pm »
How it is work: calculations of sine function on avr cost few kB of code added once for near all math functions but when I was trying to calculate sine function on Cortex M0+ it cost more than 16kB code and much SRAM so it was useles on 32 kB devices.
It was on PSoC4 cy4245axi uC.

Calculate FFT and IFFT on avr is slow but cost 5kB flash but on fancy 48MHz uC is unobtainable. Is this GCC configurations or default libraries? How to use sin or exp on Cortex M0+?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12497
  • Country: us
    • Personal site
Re: Cortex M0+ math lib
« Reply #1 on: November 19, 2023, 05:03:52 pm »
Generic GCC libraries are not extremely optimized specifically for Cortex-M0. One thing you can do to reduce the code size is to make sure you are only using single precision values and function.

This code is 12.6 KB:
Code: [Select]
  volatile float a = 123.456;
  volatile float b = sin(a);
And this code is 8.3 KB:
Code: [Select]
  volatile float a = 123.456f;
  volatile float b = sinf(a);

Also note that the function itself is small, but it calls a lot of common support code, so incremental size increase is less significant after you take the first hit.

There are likely hand-optimized versions of the FTT, but I have not looked for them.
Alex
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6934
  • Country: es
Re: Cortex M0+ math lib
« Reply #2 on: November 19, 2023, 05:39:53 pm »
Also code for arm will be larger due the different architecture, load-and-store needs more instructions as every variable address must be loaded into a register before accessing it, avr and pic can do this with one instruction most of the time, except when requiring bank switching.

Also avr code likely used simple floats instead doubles.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline analitykTopic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: pl
Re: Cortex M0+ math lib
« Reply #3 on: November 19, 2023, 05:40:59 pm »
There is not problem with FFT itself but definitely with sin, cos and exp function.
 

Offline ArdWar

  • Frequent Contributor
  • **
  • Posts: 771
  • Country: sc
Re: Cortex M0+ math lib
« Reply #4 on: November 19, 2023, 05:41:42 pm »
Try using size optimized library like picolibc or newlib-nano instead and see if there's improvement. Heck, that should be de facto "standard" library for most MCU projects.

The standard glibc are optimized for portability and isn't exactly known for its compactness or speed. However it still shouldn't be 16KB, hmm...
« Last Edit: November 19, 2023, 05:43:21 pm by ArdWar »
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6934
  • Country: es
Re: Cortex M0+ math lib
« Reply #5 on: November 19, 2023, 05:43:54 pm »
But, as you've been told, use sinf, cosf, expf, otherwise you'll be using doubles, with much larger and slower libs than single precision floats.
Probably he's using newlibnano already, most if not all arm-gcc toolchains use it?
« Last Edit: November 19, 2023, 05:48:37 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1833
  • Country: de
Re: Cortex M0+ math lib
« Reply #6 on: November 19, 2023, 05:44:43 pm »
Calculate FFT and IFFT on avr is slow but cost 5kB flash but on fancy 48MHz uC is unobtainable. Is this GCC configurations or default libraries? How to use sin or exp on Cortex M0+?

To compute the FFT, you typically don't evaluate sin/cos on the fly, but use a pre-calculated sin/cos lookup table.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 6966
  • Country: li
Re: Cortex M0+ math lib
« Reply #7 on: November 19, 2023, 05:45:30 pm »
.. and do not include printf()..
Readers discretion is advised..
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 5833
  • Country: dk
Re: Cortex M0+ math lib
« Reply #8 on: November 19, 2023, 05:54:16 pm »
Generic GCC libraries are not extremely optimized specifically for Cortex-M0. One thing you can do to reduce the code size is to make sure you are only using single precision values and function.

This code is 12.6 KB:
Code: [Select]
  volatile float a = 123.456;
  volatile float b = sin(a);
And this code is 8.3 KB:
Code: [Select]
  volatile float a = 123.456f;
  volatile float b = sinf(a);

Also note that the function itself is small, but it calls a lot of common support code, so incremental size increase is less significant after you take the first hit.

There are likely hand-optimized versions of the FTT, but I have not looked for them.

there's also arm_math.h and lib, though I don't know if it is optimized for size or performance
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1833
  • Country: de
Re: Cortex M0+ math lib
« Reply #9 on: November 19, 2023, 06:09:44 pm »
To compute the FFT, you typically don't evaluate sin/cos on the fly, but use a pre-calculated sin/cos lookup table.

And on a CPU without an FPU, you might consider doing your computations in fixed-point if speed is important.

there's also arm_math.h and lib, though I don't know if it is optimized for size or performance

For Cortex-M, there is also the CMSIS-DSP library, which also includes fast sin/cos functions (for float, q15, q31), and a set of FFT functions.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 5833
  • Country: dk
Re: Cortex M0+ math lib
« Reply #10 on: November 19, 2023, 06:20:21 pm »
there's also arm_math.h and lib, though I don't know if it is optimized for size or performance

For Cortex-M, there is also the CMSIS-DSP library, which also includes fast sin/cos functions (for float, q15, q31), and a set of FFT functions.


that's the lib for with arm_math.h
 
The following users thanked this post: gf

Offline AVI-crak

  • Regular Contributor
  • *
  • Posts: 151
  • Country: ru
    • Rtos
Re: Cortex M0+ math lib
« Reply #11 on: November 19, 2023, 06:58:49 pm »
Stop raping the Cortex M0, it's in a lot of pain.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 30368
  • Country: nl
    • NCT Developments
Re: Cortex M0+ math lib
« Reply #12 on: November 19, 2023, 07:07:53 pm »
How it is work: calculations of sine function on avr cost few kB of code added once for near all math functions but when I was trying to calculate sine function on Cortex M0+ it cost more than 16kB code and much SRAM so it was useles on 32 kB devices.
It was on PSoC4 cy4245axi uC.

Calculate FFT and IFFT on avr is slow but cost 5kB flash but on fancy 48MHz uC is unobtainable. Is this GCC configurations or default libraries? How to use sin or exp on Cortex M0+?
Probably the libraries. This is the right time to take a look under the hood and see what gets linked into the executable. The best way is to let the linker create a map file; this file shows the size of each function and variable in memory (and where it comes from) which is super useful information. Likely there are options in the IDE to choose which libraries to use.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 11383
  • Country: fi
Re: Cortex M0+ math lib
« Reply #13 on: November 19, 2023, 07:21:09 pm »
Often a simple lookup table and fixed point numbers get the job done. Also if you can convert angles into 2*pi rad == 2^n (e.g., 360 degrees = 256 units), then you can directly lookup a table like sine_table[(uint8_t)angle] for 256 elements with automagic zero-cost wrap-around, or sine_table[angle&mask] for other values of 2^n. You can even bake in any constant multipliers into the table itself for further savings.

What are your accuracy requirements, i.e. what are you doing?
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 5833
  • Country: dk
Re: Cortex M0+ math lib
« Reply #14 on: November 19, 2023, 08:48:49 pm »
Often a simple lookup table and fixed point numbers get the job done. Also if you can convert angles into 2*pi rad == 2^n (e.g., 360 degrees = 256 units), then you can directly lookup a table like sine_table[(uint8_t)angle] for 256 elements with automagic zero-cost wrap-around, or sine_table[angle&mask] for other values of 2^n. You can even bake in any constant multipliers into the table itself for further savings.

What are your accuracy requirements, i.e. what are you doing?

that is basically what is in the CMSIS DSP lib, https://github.com/ARM-software/CMSIS_4/tree/master/CMSIS/DSP_Lib/Source/FastMathFunctions
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17830
  • Country: fr
Re: Cortex M0+ math lib
« Reply #15 on: November 19, 2023, 10:08:07 pm »
If you absolutely need floating point (not sure), you can have a look at that: https://www.quinapalus.com/qfplib.html
Great stuff.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
Re: Cortex M0+ math lib
« Reply #16 on: November 19, 2023, 10:08:39 pm »
Also code for arm will be larger due the different architecture, load-and-store needs more instructions as every variable address must be loaded into a register before accessing it, avr and pic can do this with one instruction most of the time, except when requiring bank switching.

Why do people confidently post information that is false, especially when it can be easily checked? We just had someone in another thread claim that AVR passes function arguments on the stack.

https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set

AVR also has a "load-and-store" architecture. The load and store instructions do only that. The arithmetic instructions take all their operands from registers and put the result in registers.

Cortex-M0 instructions and AVR instructions are the same size, 2 bytes, but as the Arm is dealing with data 4 bytes at a time while the AVR is operating on 1 byte at a time (except MOVW, ADDIW, SUBIW, which operate on two 1-byte registers) you will find that if you are dealing with values larger than 1 byte then for the same algorithm Arm code will always be smaller than AVR code because the AVR needs 4 instructions to deal with 4-byte values -- and a lot more instructions than that for multiply.

I guess it's good in a way that people can successfully use these devices just using C without really knowing what is going on underneath.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 5833
  • Country: dk
Re: Cortex M0+ math lib
« Reply #17 on: November 19, 2023, 10:42:33 pm »
Also avr code likely used simple floats instead doubles.

afaik avr-gcc implements all floating-point arithmetic both 'float' and 'double' as 32-bit
 

Offline analitykTopic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: pl
Re: Cortex M0+ math lib
« Reply #18 on: November 19, 2023, 11:01:27 pm »
So many replies, i was not expect that.

First of all - I used the DSP in CM-SIS from ARM on a much larger uC (SAME70Q21 - 300MHz cortex m7 with so many kB of flash.... those few kB were not a problem at the time, so I didn't worry about it then). Everything worked as expected.

My goal is to use as little flash per code (and SRAM, there is only 4kB) as practically possible. This time I collected (saved) the data and the speed of calculations does not matter, although I expect faster calculations than on the AVR. I know that there is no FPU, even the basic instruction set is smaller, but I still think that the calculation of the sine function should not cost 20kB of flash.

Comparasion with AVR is good in terms of code size. Why we can not use avr library on Cortex M0+? Single floating-point arithmetic is good enough for me.

I'll check dsp from cmsis package and if it doesn't bring a solution, I'll come back here. 

deepl is good bro
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
Re: Cortex M0+ math lib
« Reply #19 on: November 19, 2023, 11:20:59 pm »
Also avr code likely used simple floats instead doubles.

afaik avr-gcc implements all floating-point arithmetic both 'float' and 'double' as 32-bit

That is correct. Also the FP functions are optimised for speed and small code, not strict IEEE-754 compliance and 0.5 ULP accuracy on basic functions like the Arm ones will be.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 30368
  • Country: nl
    • NCT Developments
Re: Cortex M0+ math lib
« Reply #20 on: November 19, 2023, 11:56:08 pm »
Comparasion with AVR is good in terms of code size. Why we can not use avr library on Cortex M0+? Single floating-point arithmetic is good enough for me.
If you have the source code for the AVR library AND it is all written in C, you should be able to compile it for ARM without much trouble. I have been using the C library that comes with very old versions of MSP430-GCC for my ARM projects for ages because it is so small.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
Re: Cortex M0+ math lib
« Reply #21 on: November 20, 2023, 12:55:12 am »
Comparasion with AVR is good in terms of code size. Why we can not use avr library on Cortex M0+? Single floating-point arithmetic is good enough for me.
If you have the source code for the AVR library

Everyone does.

https://github.com/avrdudes/avr-libc/tree/main/libm/fplib

Quote
AND it is all written in C

Ahahahahahaha.
 
The following users thanked this post: SiliconWizard

Offline tridac

  • Regular Contributor
  • *
  • Posts: 142
  • Country: gb
Re: Cortex M0+ math lib
« Reply #22 on: November 20, 2023, 01:00:38 am »
Math libs are often not that efficient, because they are expected  to handle generalised conditions. Try to avoid math lib for embedded work, and prefer to use, depending on resolution, for example, a single quadrant sine lookup table, then perhaps interpolate for finer resolution. Say, use a 1 k lookup table, single quadrant, then use reflection and inversion for the remaining quadrants. Much faster than brute force calculation and more memory efficient as well. Optimise for the project requirements etc...
« Last Edit: November 20, 2023, 01:03:50 am by tridac »
Test gear restoration, hardware and software projects...
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6934
  • Country: es
Re: Cortex M0+ math lib
« Reply #23 on: November 20, 2023, 04:59:19 am »
AVR also has a "load-and-store" architecture.
Yep, sorry, I never used AVR, for some reason I mistakenly thought they were Harvard architecture like PICs.

Check this CM0 math lib, states to use only 1KB:
https://github.com/mysterywolf/Qfplib-M0-tiny

You have to set include_scientific=1 :
Quote
If the symbol include_scientific is set to 1 (which implies setting include_conversions to 1), then the following functions are included: qfp_fcos, qfp_fsin, qfp_ftan, qfp_fatan2, qfp_fexp, qfp_fln and qfp_fsqrt.
« Last Edit: November 20, 2023, 05:05:36 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6464
  • Country: nz
Re: Cortex M0+ math lib
« Reply #24 on: November 20, 2023, 06:55:54 am »
AVR also has a "load-and-store" architecture.
Yep, sorry, I never used AVR, for some reason I mistakenly thought they were Harvard architecture like PICs.

They are.

Harvard and load/store (the main part of RISC) are unrelated properties.

Harvard architecture means instructions and data come on different buses -- traditionally different address spaces -- so that loads and stores do not interfere with fetching the next instruction.

High performance CPUs such as in PCs have been pseudo-Harvard since the 80386 and 68020 (and even, optionally, Cortex M7) in that they fetch instructions from a small instruction cache, which is in the same address space as data but keeps copies of recently used instructions. From time to time the instruction cache has to be synchronised with any changes made to those memory locations by the data bus side of the CPU.

Arm's load/store (or push/pop) multiple registers instructions were included primarily to decrease instruction fetch conflicts. They are not so useful (at least for speed) if you have an icache and Arm dropped them in Arm64.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->