Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: Help needed:- what's the quickest way to store 256 bytes of data?

2006-02-13 by thekenhunt

Ned
  Many thanks for the feedback. I think 3 cycles/byte is about as good
as it gets.. 8o) 

cheers

Ken

--- In AVR-Chat@yahoogroups.com, Ned Konz <bikenomad@...> wrote:
>
> 
> On Feb 13, 2006, at 9:26 AM, thekenhunt wrote:
> 
> > I have an application which needs to store 256 bytes of data. My
> > current (C) solution is way too slow. Could anyone point me to the
> > fastest way to go about reading a fixe number of bytes into an
> > array/memory location using assembler? ie how can I replace the loop
> > below most efficiently.
> >
> > char mydata[256];
> > void myloop()
> >     {
> >     for(d=256;d;d--) mydata[d]=PIND;
> >     }
> >
> 
> Well, the first byte you're storing is past the end of mydata[],
> and you're storing from the end to the beginning.
> 
> Assuming that you wanted to store entirely inside mydata[],
> this is the output from gcc 4.0.2 with -O2:
> 
>     7:test3.c       **** void myloop(void)
>     8:test3.c       **** {
>    74                .LM0:
>    75                /* prologue: frame size=0 */
>    76                /* prologue end (size=0) */
>    77 0000 E0E0              ldi r30,lo8(mydata+255)
>    78 0002 F0E0              ldi r31,hi8(mydata+255)
>    79                .L2:
>    80                .LBB2:
>     9:test3.c       ****     for(unsigned char d=255;d;d--)
>    10:test3.c       ****         mydata[d]=PIND;
>    82                .LM1:
>    83 0004 80B3              in r24,48-0x20
>    84 0006 8083              st Z,r24
>    85 0008 3197              sbiw r30,1
>    87                .LM2:
>    88 000a 80E0              ldi r24,hi8(mydata)
>    89 000c E030              cpi r30,lo8(mydata)
>    90 000e F807              cpc r31,r24
>    91 0010 C9F7              brne .L2
> 
> That would be 1+2+2+1+1+2 = 9 cycles / byte
> 
> And using a pre-decremented pointer helps a little bit:
> 
> 
>     7:test3.c       **** void myloop(void)
>     8:test3.c       **** {
>    74                .LM0:
>    75                /* prologue: frame size=0 */
>    76                /* prologue end (size=0) */
>    77 0000 E0E0              ldi r30,lo8(mydata+256)
>    78 0002 F0E0              ldi r31,hi8(mydata+256)
>    79                .L2:
>     9:test3.c       ****     char* p=mydata+256;
>    10:test3.c       ****
>    11:test3.c       ****     do
>    12:test3.c       ****     {
>    13:test3.c       ****         *--p=PIND;
>    81                .LM1:
>    82 0004 80B3              in r24,48-0x20
>    83 0006 8293              st -Z,r24
>    14:test3.c       ****     }
>    15:test3.c       ****     while (p >= mydata);
>    85                .LM2:
>    86 0008 80E0              ldi r24,hi8(mydata)
>    87 000a E030              cpi r30,lo8(mydata)
>    88 000c F807              cpc r31,r24
>    89 000e D0F7              brsh .L2
> 
> For 1+2+1+1+1+2 = 8 cycles/byte
> 
> Of course, you could always unroll the loop:
> 
>     7:test3.c       **** void myloop(void)
>     8:test3.c       **** {
>    74                .LM0:
>    75                /* prologue: frame size=0 */
>    76                /* prologue end (size=0) */
>     9:test3.c       ****     mydata[255] = PIND;
>    78                .LM1:
>    79 0000 80B3              in r24,48-0x20
>    80 0002 8093 0000         sts mydata+255,r24
>    10:test3.c       ****     mydata[254] = PIND;
>    82                .LM2:
>    83 0006 80B3              in r24,48-0x20
>    84 0008 8093 0000         sts mydata+254,r24
>    11:test3.c       ****     mydata[253] = PIND;
>    86                .LM3:
>    87 000c 80B3              in r24,48-0x20
>    88 000e 8093 0000         sts mydata+253,r24
> 
> I can't imagine it getting much faster than that.
> 
> That would be 3 cycles / byte
> * 256 = 768 cycles for 256 bytes.
> 
> It's also 768 words (1536 bytes) of code, but you wanted fast...
> 
> -- 
> Ned Konz
> ned@...
>

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.