Yahoo Groups archive

AVR-Chat

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

Message

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

2006-02-13 by Ned Konz

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@bike-nomad.com

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.