CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

cant make it work the locate !

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cagabit



Joined: 19 Dec 2014
Posts: 7

View user's profile Send private message

cant make it work the locate !
PostPosted: Fri Dec 19, 2014 9:11 am     Reply with quote

Hi to all,

Have a project ongoing and have some timing performance problems. Thought to convert some math functions to ASM to gain some cycles. Not very experienced on ASM.

For pic 18f2550, using v5.015

I want to make a function, and put the asm part in it.
if I am not wrong, the variables must be on the same page, for the asm code to directly get or set them ??! To test this i wrote this small code :

Code:

   int16 dat[6]={10001,10002,10003,10004,10005,10006};
   #locate dat=0x50
   int16 refA = 20250;
   #locate dat=0x5C
   int16 refB = 20020;
   #locate dat=0x5E
   float ktemp[4]={10008,10009,10010,10011};
   #locate dat=0x50


But from the debug RAM window or the "printf ... &variable" code they are not on the place i set. Compiler is not putting these variables to the address i wrote, something beyond my knowledge is happening here !

Also as far as i get from the posts, i should not save the state of some registers and reload at the end of the function, since there is no interrupt, is it true ? Can i directly get the values and do some math and set the result to the variable from the ASM code ?

Any guidance is appreciated. Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Fri Dec 19, 2014 9:32 am     Reply with quote

If you access the variables by name in the assembler, CCS will automatically handle the bank switching for you. They can be left in their normal location.
The reason they won't 'locate' is that you are trying to place them in the access RAM, and the compiler uses this already to speed the access to important variables.
What is the actual function you want to recode?. Most of the standard functions are very close to optimal.
Interrupts save and restore registers when they happen.

Look at the example given under #ASM in the manual.
It shows how you access variables by name, and how to return a value from a function.
cagabit



Joined: 19 Dec 2014
Posts: 7

View user's profile Send private message

PostPosted: Fri Dec 19, 2014 10:00 am     Reply with quote

Thanks, great summary.

Then i can directly test the function. The C code trying to convert is :

Code:

dat[1]=dat[1] *  ktemp[1];
tt= logt[dat[1]];
if(RefA > tt)
   dat[1]= ((int32)(RefA-tt)*1000)/RefB ;
else dat[1]=0;
if (dat[1]>1000) dat[1]=1000;


All variables 16-bit except ktemp[] is float, it is a coefficient actually.
Logt is logarithm table consisting 1024 elements, i load the result from table to a temporary variable tt, because of some problems. And as far as I can measure this part is taking 108uS with 48Mhz osc. ( Also USB is active to transfer the data to PC ).

I am trying to measure the speed of a liquid which passes 2 lines of led barriers. Get the instant level with A/D and try to calibrate with this code snippet. After this I have to make cross-correlation also to calculate the time lag between 2 signal arrays. Which i will come to that after this.

The test measurements make me suspect that I can not read frequent enough so I am trying to shorten the read & calibrate part.

I thought some gain can be accomplished with converting this to ASM ? What do you think ?

Thanks,
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Fri Dec 19, 2014 12:02 pm     Reply with quote

First thing is that ktemp, being a float, forces float multiplication on the first line. That is about 40uSec of your time straight away.

The rest is almost all the division. Division is foul. costs about 5* as much as multiplication. It'd actually be faster if you stored 1000/RefB as a float, and multiplied by this!. I'd suggest you try simply storing 1000/RefB as a float when it is generated, and in this code just do the one float multiply by this. That ought to save perhaps 30uSec.
Microchip do a carefully optimised assembler maths library, and the times of the CCS routines are within a couple of cycles of the times from this, so you are not going to improve much with the current approach.
Other thing to consider, is scaling.
For instance, if you stored ktemp*256 as an int32, again when it is generated, then you might be able to do the first line as:
Code:

dat[1]=(dat[1] *  ktemptimes)/256;


Using int32 arithmetic. The /256, is one of the 'exceptions' to division being horrible, since the compiler can do this using rotation (and will do).
At least another 10uSec saved inside this routine.....
cagabit



Joined: 19 Dec 2014
Posts: 7

View user's profile Send private message

PostPosted: Sat Dec 20, 2014 7:52 am     Reply with quote

Thank you Ttelmah.

Really got the point, no need for ASM, the DIV and /256 trick will save my day i think. The time gain will be enough i think.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group