View previous topic :: View next topic |
Author |
Message |
Imanjl
Joined: 15 Nov 2004 Posts: 42
|
Float to Int32 execution time |
Posted: Sun Aug 25, 2013 4:15 am |
|
|
I faced to a problem in using Float_To_Int32 function, the problem is that converting a float variable or even float constant with value “0.0” takes 4 times longer than other values like 0.004, 0.1, 0.00078 etc. This is not happened in converting a float to 16bit integer.
For 80mhz 40MIPS dsPIC 33fj256mc710 :
1-Execution time for converting a float number to int16 = 3-6 us (seems normal)
2-Execution time for converting a float number to int32 = 10-11 us (seems normal)
3-Execution time for converting 0.0 float to int32 = 37uS (Not Normal) !!!!
Example program :
Code: |
{
float tempf;
int32 temp32;
tempf = 0.0;
temp32 = tempf; // takes 37us to execute !
tempf = 0.005;
temp32 = tempf; // takes 11us to execute.
} |
Compiler version 4.120 (also tested on the latest 5.x version with the same result).
Any idea about this ? Can you get the same result ? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Aug 25, 2013 6:45 am |
|
|
The long calculation time is due to the simple design of the conversion function. You can save considerable
time if you test the highest exponent bit (bit 30 of the 32-bit float value). If it's zero, the converted integer
value will be zero, too. |
|
|
Imanjl
Joined: 15 Nov 2004 Posts: 42
|
|
Posted: Sun Aug 25, 2013 11:05 am |
|
|
FvM wrote: | if you test the highest exponent bit (bit 30 of the 32-bit float value). If it's zero, the converted integer value will be zero, too. |
It works ! tnx for suggestion.However I found a solution and compare the float variable to "0" which takes a bit longer. But bit_test seems to be the fastest way.
Note that this solution will add extra lines to code and increase complexity, I have several math functions which must be edited one by one. I believe you agree that in the code below "A" looks better and simpler than "B". I Hope this issue will be solved in the future releases.
Code: | {
float tempf;
int32 temp32;
tempf = 0.0;
if (!bit_test(tempf,30) temp32 = 0; //B
else temp32=tempf; //B
temp32 = tempf; //A
} |
Last edited by Imanjl on Tue Aug 27, 2013 2:45 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sun Aug 25, 2013 3:20 pm |
|
|
Though 'testing for zero', catches the 'worst case' for the algorithm used. Unfortunately, it'll be nearly as bad for small values close to zero. So a 'non zero', but still representable value like 1E-38 will take almost exactly as long.
I ran into this years ago, when writing a maths library for another chip. to do it 'efficiently', you have to test for the value being below 1. I did it by testing the exponent, for being inside the range that could generate a integer of one or greater.
So, though it adds 41 instructions to the 'normal' situation:
Code: |
if (val<1.0) fresult=0;
else fresult=val;
|
Is 'better' if you are likely to meet 'small non zero values'.
Best Wishes |
|
|
Imanjl
Joined: 15 Nov 2004 Posts: 42
|
|
Posted: Sun Aug 25, 2013 3:51 pm |
|
|
Yes I also noticed that it is not only happened for zero, but also all values between 0.0-1.0. For Values closer to zero like (1E-15, 1E-30, 1E-38) it takes longer and longer and the worst case is zero.
Anyway the best solution is Ttelmah's one for sure. |
|
|
|