Dear all,
I have an experience to develop C code for different microcontrollers and DSPs. However, this is first time to develop code for Arm Core microcontrollers. I am using STM32F334 and STM32F745 for different projects. Last couple of weeks, I have learnt to control peripherals and I hadn't calculated any mathematical expression. I started to write mathematical calculations and I realized they took a lot of time.
For example:
uint16_t Middle, Low, High;
--------------------
Middle = ((Low + High) * 0.5);
This code takes ~6.25us. Actually, it adds two unsigned integer and one floating point multiplication. It should be very fast because STM32F334 has FPU. I used this code for Texas Instrument TMS320F335. (Texas Complier understand 0.5 is floating and no need to declared again.) I searched on internet and I revised some sample codes and I realized that I should write (float)0.5 or 0.5f. Then I changed the code as like below:
Middle = ((Low + High) * 0.5f);
This new code takes 259ns. Which is ~24 times faster than previous code. (I have developed many codes for TMS320F28335 and they worked well. I thought it was in C and this is also in C languages and it should work.) One letter makes the execution time much faster. I also tried to understand if I need to declared integer number or casting floating point number into integer number but I observed no need to do it. For example:
Middle = (uint16_t) ((Low + High) * 0.5f); is exactly consumes same time with Middle = ((Low + High) * 0.5f);
or Middle = 34; takes same time with Middle = (uint16_t)34;...
Another example:
#define Offset 5.0f
#define Correction 1.002f
volatile float Voltage;
--------------------------
Voltage = ((ADC1->DR) - Offset)*Correction;
-------------------------
ADC1->DR is 32-bit unsigned integer and all others are floating numbers. I was not sure if I have to write the code as below:
Voltage = ((float)(ADC1->DR) - Offset)*Correction;
I tried and I didn't see any difference. So, time is very crucial in my code. I have to write an optimum code as much as I can. That is why I don't use HAL function and I wrote my own functions. I searched documents to learn how to define variables or how to handle different data type in one equation. I think it is about Arm Complier and I had a look to Arm complier user guide. However, I didn't find any enough explanations.
I would like to ask you if you have a document/sample codes and etc, could you please share me.
Last thing that: if Offset is greater than 31.0f, the execution time is more than if the offset is lower than 32.0f. What is the relation?
#define Offset 32.0f It is slower... 2^5 = 32? It took few hundreds nanosecond more than if Offset is 31.0f.
Thank you very much in advance.
Regards
What toolchain are you using?
Did you have the FPU enabled in all cases?
Remember that standard 'C' treats an "unadorned" floating constant as double.
Floating point will always take longer than integer arithmetic.
So, unless you really need it, stick to integer arithmetic!
Especially when it comes to something like a simple divide by 2 - which can be implemented as a shift.
https://floating-point-gui.de/
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html