Forum: Mikrocontroller und Digitale Elektronik Bitfields: Speicherplatzoptimierung


von matze (Gast)


Lesenswert?

Hallo,

ich bin dabei mein kleines Programm für einen ATtiny zu optimieren, was 
den Speicherbedarf angeht. Dabei ist mir folgendes Aufgefallen:
1
typedef struct MyStruct
2
{
3
  char a : 1;
4
  char b : 1;
5
  char c : 1;
6
  char d : 3;
7
8
} MyStruct;
9
MyStruct myStruct;
10
11
12
void myFunction()
13
{
14
    myStruct.a ^= 1;    // Diese Anweisung benötigt 14 Byte
15
}

Ich möchte oben markierte Anweisung gerne verwenden, aber nicht für den 
Preis von 14 Byte!

Wie kann ich das günstiger realisieren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> mein kleines Programm für einen ATtiny zu optimieren, was
> den Speicherbedarf angeht
Welchen Speicherbedarf?
Den vom RAM oder dem vom Flash oder dem vom EEPROM?

von matze (Gast)


Lesenswert?

Flash!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dann nimm besser für jedes Flag ein einzelnes Byte. Sonst muß der 
Compiler jedes Bit aus dem Byte herauspfriemlen, es manipulieren und 
wieder hineinbiegen...
Das braucht etliche Assemblerzeilen und Platz im Flash  :-o

von Peter (Gast)


Lesenswert?

kannst du uns auch mal den ASM code zeigen, das man sieht warum das 
ganze 14byte braucht?

von matze (Gast)


Lesenswert?

Ok,

der Vorteil der Bitfields ist also nur der, dass weniger RAM verbraucht 
wird, aber auf kosten von mehr Flash und Prozessorzyklen?

von Falk B. (falk)


Lesenswert?

Jep

von matze (Gast)


Lesenswert?

Ok,

wenn ich ein Byte pro Flag verwende, also in etwa so:
1
unsigned char a;
2
3
void myFunction()
4
{
5
    a = 0;
6
    while(1)
7
    {
8
        a ^= 1;    // Diese Anweisung benötigt 10 Byte!
9
    }
10
}

dann braucht die Anweisung leider immernoch 10 Byte!

Geht das nicht billiger?

von (prx) A. K. (prx)


Lesenswert?

Eher nicht. Laden = 4 Bytes, XOR = 2 Bytes, speichern = 4 Bytes. Kürzer 
gibt's das beispielsweise auf 8051.

von matze (Gast)


Lesenswert?

Ok, dann finde ich mich damit ab, dass das 10 Byte kostet...

von Gast (Gast)


Lesenswert?

1
#define FLAG_A 0x01
2
#define FLAG_B 0x02
3
#define FLAG_C 0x04
4
5
unsigned char Flags;
6
7
void myFunction()
8
{
9
    Flags ^= FLAG_A;
10
}

von Bernhard R. (barnyhh)


Lesenswert?

@ matze

Muß diese Variable tatsächlich global sein?

Funktionsinterne Variable liegen vielfach in Registern, so daß eine 
Bitinversion nur 2 Bytes (1 Instruktion) kostet.

Bernhard

von (prx) A. K. (prx)


Lesenswert?

Für besonders platz/zeitkritische Flags gibt es bei manchen AVRs ein 
paar freie Bytes im bitadressierbaren I/O-Raum, GPIORA-C oder so. Die 
sind effizienter, wenn auch eher beim Setzen und Löschen (2 Bytes), 
nicht ganz so sehr beim XOR (6 Bytes).

von matze (Gast)


Lesenswert?

Hmm... ok. Dann werde ich mal versuchen, die Flags (zumindest einen Teil 
davon) in die Funktion zu verschieben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.