Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Why RAM usage increases drastically with this function in XC8 compiler?

Status
Not open for further replies.

xpress_embedo

Advanced Member level 4
Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,154
Helped
161
Reputation
396
Reaction score
189
Trophy points
1,353
Location
India
Activity points
10,591
Hello!,
I am using PIC12F1571 micro-controller do develop an application, this micro-controller has very less RAM, just 128 bytes, so while designing this application, i have to take care of RAM also.
I need to calculate average on an array, can anyone please tell me, why RAM and ROM size gets changes drastically by using the function for that.

Here is case1, when i didn't used function for computing average.
In this case RAM = 54 bytes and ROM = 335 bytes
Case1.png

Now case 2, where i used function for computing average, and the function is as follow:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
uint16_t Compute_Average( uint8_t *data, uint8_t data_size)
{
  uint16_t total;
  for ( uint8_t i = 0; i<data_size; i++ )
  {
    total += *(data+i);
  }
  total = total/data_size;
  return total;
}



RAM = 65 bytes and ROM = 393 bytes
So 11 bytes increased in RAM and 58 bytes in ROM, can someone please help me in understanding this thing.
Case2.png
Thanks in advance.
 

The answer is at your finger tips, just need to review the symbol and disassembly listings.

I guess the run-time library division routine will eat up some resources, presumed it's not yet used in your code before.
 
Ram usage in any C compiler depends on the individual functions and optimizations used in the calculation so it can be efficient but unpredictable. You have little control over it I'm afraid.

You could experiment though to see if it can be reduced, for example the "for" loop working out the total may be more efficiently written as :
Code:
i = OV_UV_SIZE;
while (i--) total+= OV_UV_Values[i];
on the basis that PIC have instructions for detecting if a variable is zero so it's easier to count 'i' down than compare it against another value each time it loops.

Brian.
 
The answer is at your finger tips, just need to review the symbol and disassembly listings.

I guess the run-time library division routine will eat up some resources, presumed it's not yet used in your code before.

Yes you are right, the long division library (lwdiv.c) is included when i used that function, and yes this is the first time I am using the division in my program.

I didn't understand one thing, in the first case, why this library is not included and why only in second case.

- - - Updated - - -

Ram usage in any C compiler depends on the individual functions and optimizations used in the calculation so it can be efficient but unpredictable. You have little control over it I'm afraid.

You could experiment though to see if it can be reduced, for example the "for" loop working out the total may be more efficiently written as :
Code:
i = OV_UV_SIZE;
while (i--) total+= OV_UV_Values[i];
on the basis that PIC have instructions for detecting if a variable is zero so it's easier to count 'i' down than compare it against another value each time it loops.

Brian.

Thanks for your suggestion, the size is increased due to the inclusion of division library.

I tried your Optimization technique but nothing changes in my case.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uint16_t Compute_Average( uint8_t *data, uint8_t data_size)
{
  uint16_t total;
//  uint8_t i = 0;
//  for ( i = 0; i<data_size; i++ )
//  {
//    total += *(data+i);
//  }
  uint8_t i = data_size;
  while(i--)
  {
    total += *(data+i);
  }
  total = total/data_size;
  return total;
}



Thanks for this, i will use it another PIC projects , i am sure it will work on PIC16 or PIC18 micro-controllers.
 

Code snippets are unfortunately incomplete. I can just guess that OV_UV_SIZE is a power of two, so /OV_UV_SIZE can be implemented as a cheap shift operation. Using a function parameter for the value blocks this option. Optimization with inline expansion of functions might re-enable the option, depending on the function instantiation details.

But generally, think twice when writing C code for a tiny processor.

Again, by reviewing "case 1" disassembly, you'll see what's going on.
 
Code snippets are unfortunately incomplete. I can just guess that OV_UV_SIZE is a power of two, so /OV_UV_SIZE can be implemented as a cheap shift operation. Using a function parameter for the value blocks this option. Optimization with inline expansion of functions might re-enable the option, depending on the function instantiation details.

But generally, think twice when writing C code for a tiny processor.

Again, by reviewing "case 1" disassembly, you'll see what's going on.

Thank you so much, you are correct, the value of macro is 8, and division can be implemented by left shifting by 3 and hence no need to use actual division operator in that case, and then in second case, since i created a function for that, the size value is unknown and that's why compiler used division library.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top