View previous topic :: View next topic |
Author |
Message |
rbarbali
Joined: 17 Dec 2015 Posts: 8
|
ROM size with int1 vs int8 |
Posted: Tue Aug 24, 2021 12:37 pm |
|
|
CCS V5.083, PIC16F18875
Hi. I am trying to reduce the rom size of a program. I decide to use int1 vars instead of int8 vars thinking the ROM size will be reduced. But I get that using 8 bits vars consumes less ROM than using 1 bit vars. What am I missing?
The int1 version:
Code: | #include <16f18875.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#use delay(clock= 20M)
int8 i, j, k;
int1 flag_open_tamper_sent[16];
int1 flag_closed_tamper_sent[16];
int1 flag_low_batt_sent[16];
int1 flag_normal_batt_sent[16];
int1 flag_lost_link_sent[16];
int1 flag_normal_link_sent[16];
void main(void)
{
for(k = 0; k < 16; k++)
{
flag_open_tamper_sent[k] = 0;
flag_closed_tamper_sent[k] = 1;
flag_low_batt_sent[k] = 0;
flag_normal_batt_sent[k] = 1;
flag_lost_link_sent[k] = 0;
flag_normal_link_sent[k] = 1;
}
} |
LST file:
ROM used: 113 words (1%)
Largest free fragment is 2048
RAM used: 31 (3%) at main() level
46 (4%) worst case
Stack used: 0 locations
Stack size: 16
The int8 version:
Code: | #include <16f18875.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#use delay(clock= 20M)
int8 i, j, k;
int8 flag_open_tamper_sent[16];
int8 flag_closed_tamper_sent[16];
int8 flag_low_batt_sent[16];
int8 flag_normal_batt_sent[16];
int8 flag_lost_link_sent[16];
int8 flag_normal_link_sent[16];
void main(void)
{
for(k = 0; k < 16; k++)
{
flag_open_tamper_sent[k] = 0;
flag_closed_tamper_sent[k] = 1;
flag_low_batt_sent[k] = 0;
flag_normal_batt_sent[k] = 1;
flag_lost_link_sent[k] = 0;
flag_normal_link_sent[k] = 1;
}
} |
ROM used: 81 words (1%)
Largest free fragment is 2048
RAM used: 118 (12%) at main() level
128 (12%) worst case
Stack used: 0 locations
Stack size: 16[/code]
Regards |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 306
|
|
Posted: Tue Aug 24, 2021 12:57 pm |
|
|
Array access on bits takes more program commands. An array of 16 bits spans two bytes so it first has to determine which byte to access and then which bit inside that byte. With an array if int8, it is just starting address and offset. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9270 Location: Greensville,Ontario
|
|
Posted: Tue Aug 24, 2021 2:59 pm |
|
|
gee, you used less than 1% of ROM, I wouldn't worry until you used 80+%, THEN look at space saving tricks.... |
|
|
rbarbali
Joined: 17 Dec 2015 Posts: 8
|
|
Posted: Tue Aug 24, 2021 5:08 pm |
|
|
Thanks gaugeguy & temtronic!
Actually I am using 97% of the 16f18875, so I am looking for methods of reducing the size of the program even more. One way I found is replacing INT1s for INT8s definitions, but I wanted to know if I was doing something bad.
As per your suggestion I found: https://www.ccsinfo.com/forum/viewtopic.php?t=43389&highlight=space+saving+tricks
I will continue searching for more tricks... |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 482 Location: Montenegro
|
|
Posted: Tue Aug 24, 2021 7:33 pm |
|
|
Bigger PIC, like 16f18877? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19590
|
|
Posted: Wed Aug 25, 2021 12:07 am |
|
|
The 'key' that has been mentioned, is the 'array access'.
int1 fred;
Then
fred=1;
or
fred=0;
Generates very efficient code, and you can have eight such variables only
using one byte of RAM.
However as soon as you introduce arrays, the compiler starts having to do
lots of work. On the int8 variables, it'll have to add the index, to the
start of the array, and do indirect accesses to this. On the int1, instead
of just being able to use bit set and bit clear on the predefined bit, it
has to do the same indexed access to the bytes, but also add the extra
complexity of having to generate a mask to access the actual bit. Also
with an extra division by eight. So in your case the extra code to do this
'costs more ROM', but of course the saving is in RAM. Note 31bytes for
the int1 version, versus 118 for the int8 version.
So using int1, adds an extra level of complexity to the code for array
accesses. Costs ROM for these. However saves RAM.
Remember you can save ROM, generally by putting all the code reading
and writing to the same variables, into one place. So if you have ten
locations in your code that write a value into a particular array, then
have a single routine to do this and call this from all the locations. The
'overhead' of the call, will be less than the cost of having ten sets of
the array access code. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9270 Location: Greensville,Ontario
|
|
Posted: Wed Aug 25, 2021 4:57 am |
|
|
silly 'cheat'...
instead of
flag_open_tamper_sent[k] = 0;
use
flag_open_tamper_sent_01 = 0;
flag_open_tamper_sent_02 = 0;
...
...
...
flag_open_tamper_sent_16 = 0;
where all of them are int1.
compiler will save 8 of them per byte .
if you can, rename them for their 'use'
flag_open_tamper_switch_01_sent = 0; |
|
|
rbarbali
Joined: 17 Dec 2015 Posts: 8
|
|
Posted: Wed Aug 25, 2021 5:37 am |
|
|
PrinceNai,
Quote: | Bigger PIC, like 16f18877? |
I think so, but , due to the chip shortage, my boss bought PIC16F18875...
temtronic: Quote: | silly 'cheat'...
instead of
flag_open_tamper_sent[k] = 0;
use
flag_open_tamper_sent_01 = 0;
flag_open_tamper_sent_02 = 0;
...
...
...
flag_open_tamper_sent_16 = 0;
where all of them are int1.
compiler will save 8 of them per byte .
if you can, rename them for their 'use'
flag_open_tamper_switch_01_sent = 0; |
I will try this! |
|
|
|