|
|
View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Array addressing optimization? |
Posted: Tue Dec 07, 2004 3:50 am |
|
|
I have two different ways to address data in a buffer, one based on arrays and the other on pointers. I like the second pointer based method because it is much better to maintain, but it uses way more memory space.
Code: | int32 DateTime;
struct Header *pHeader;
char Buffer[100];
pHeader = Buffer; // Make pHeader point to Buffer
// The next line requires 40 bytes in v3.212
DateTime = EncodeTime(Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], 0);
// The next line requires 120 bytes in v3.212
DateTime = EncodeTime(pHeader->Day, pHeader->Month, pHeader->Year, pHeader->Hour, pHeader->Min, 0);
|
Are there any suggestions on how I can pass the variables and keep both the small memory print and readability? |
|
|
Ttelmah Guest
|
Re: Array addressing optimization? |
Posted: Tue Dec 07, 2004 4:58 am |
|
|
ckielstra wrote: | I have two different ways to address data in a buffer, one based on arrays and the other on pointers. I like the second pointer based method because it is much better to maintain, but it uses way more memory space.
Code: | int32 DateTime;
struct Header *pHeader;
char Buffer[100];
pHeader = Buffer; // Make pHeader point to Buffer
// The next line requires 40 bytes in v3.212
DateTime = EncodeTime(Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], 0);
// The next line requires 120 bytes in v3.212
DateTime = EncodeTime(pHeader->Day, pHeader->Month, pHeader->Year, pHeader->Hour, pHeader->Min, 0);
|
Are there any suggestions on how I can pass the variables and keep both the small memory print and readability? |
No.
The reason for the difference, is that the first version, is using constant addressess. There is no difference in accessing an array, or using a pointer, in terms of memory useage, if your first line said 'Buffer[addr]', (where 'addr' was a variable), the same code would be used as for the pointer version, and the array version. However because you code a constant in the first version (Buffer[1]), the actual address of this can be solved at compile time, rather than at runtime, and the transfer becomes the simple job of moving a byte from a known address. Conversely, using pointers, puts the whole thing into a situation where it cannot be solved until runtime, and is therefore larger.
You could consider making the array version more readable using #defines. Something like:
#define Day Buffer[1]
#define Month Buffer[2]
#define Year Buffer[3]
#define Hour Buffer[4]
#define Min Buffer[5]
DateTime = EncodeTime(Day, Month, Year, Hour, Min, 0);
Will still solve as a constant during compile, and may be more readable.
Best Wishes |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Dec 07, 2004 5:04 am |
|
|
I use a lot of these defines.
#define Day 1
#define Month 2
buffer[Day]=1;
So the constants can be used in for other things. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 07, 2004 6:34 am |
|
|
Thanks, Ttelmah and Future!
I know and have used both methods, but there is the disadvantage that a change in the data structure also requires a change in the #define's. This is error prone.
The other solution I came up with is to use a union:
Code: | union
{
char Buf[100];
struct Header Hdr;
} Buffer;
void main()
{
int32 DateTime;
struct Header *pHeader;
pHeader = Buffer;
// The next line requires 42 bytes
DateTime = EncodeTime(Buffer.Buf[1], Buffer.Buf[2], Buffer.Buf[3], Buffer.Buf[4], Buffer.Buf[5], 0);
// 122 bytes
DateTime = EncodeTime(pHeader->Day, pHeader->Month, pHeader->Year, pHeader->Hour, pHeader->Min, 0);
// 42 bytes
DateTime = EncodeTime(Buffer.Hdr.Day, Buffer.Hdr.Month, Buffer.Hdr.Year, Buffer.Hdr.Hour, Buffer.Hdr.Min, 0);
}
|
|
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Dec 07, 2004 7:15 am |
|
|
Can you make? Does it work?
union
{
char Buf[sizeof(Header)];
struct Header Hdr;
} Buffer; |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 07, 2004 7:28 am |
|
|
Quote: | Can you make? Does it work?
union
{
char Buf[sizeof(Header)];
struct Header Hdr;
} Buffer; |
Yes, this will work too. In my case though Buf is a general buffer used for other purposes as well, so that's why I want it to be larger than the size of the Header struct. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Dec 07, 2004 6:50 pm |
|
|
Quote: | Are there any suggestions on how I can pass the variables and keep both the small memory print and readability? |
Yes
How about just declaring a structure and a buffer and just locate them at the same address.
Code: |
#include <16f876.h>
#fuses HS,NOWDT,NOLVP,NOPROTECT,PUT,BROWNOUT
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#byte PORTC=7
struct
{
int hour;
int min;
int sec;
int day;
}stuff;
#locate stuff = 0x30
int buf[20];
#locate buf = 0x30
byte a;
void main()
{
stuff.hour = 1;
stuff.min = 36;
stuff.sec = 45;
stuff.day = 7;
buf[4] = 33;
do {
} while (1);
} |
|
|
|
|
|
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
|