mikrocontroller.net

Forum: Compiler & IDEs Benötige Hilfe bei Optmierung


Autor: Ulrich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich habe eine datei angehänge (Am Anfang habe ich die*.h reinkopiert)

die Funktionen benötigen 178bytes. Aber das muss kleiner werden(arbeite 
mit einem atmega8). Und ich bin auch überzeugt das es geht. Hat da 
jemand ein paar Tipps für mich?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, ist hier nicht übersetzbar.

Compiling C: adress_table.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=8000000UL -Os 
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall 
-Wstrict-prototypes -Wa,-adhlns=./adress_table.lst  -std=gnu99 -Wundef 
-MMD -MP -MF .dep/adress_table.o.d adress_table.c -o adress_table.o
adress_table.c:7: error: expected specifier-qualifier-list before 
'uint16_t'
adress_table.c:12: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'adresstable_size'
adress_table.c:14: error: expected ')' before 'x'
adress_table.c:15: error: expected ')' before 'id'
adress_table.c:16: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'getadress_table'
adress_table.c:21:18: error: main.h: No such file or directory
adress_table.c:22:26: error: adress_table.h: No such file or directory
adress_table.c:25: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'adresstable_size'
adress_table.c:27: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'find_ID'
adress_table.c:39: error: expected ')' before 'x'
adress_table.c:50: error: expected ')' before 'id'
adress_table.c:61: error: expected '=', ',', ';', 'asm' or 
'__attribute__' before 'getadress_table'
make.exe: *** [adress_table.o] Error 1

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, du musst bloß "main.h" durch <stdint.h> austauschen, dann lässt
sich das einwandfrei compilieren.

Allerdings: es gibt keinen `memory hog' unter den Funktionen, sie sind
alle gleichermaßen groß, und ich sehe auf Anhieb auch nichts, was da
großartig überflüssig wäre.

Vermutlich könnte man mit reinem Assemblergehacke mit dem 10fachen
Aufwand an Zeit da ein Viertel davon sparen, aber eine Größenordnung
spart man daran nicht mehr.

p.s.: "address" schreibt sich im Englischen mit Doppel-d.  Ist ein von
Deutschen gern gemachter Fehler.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hab ich bei -Os noch ein bischen was herausgeholt:
adresstable_t* adresstable_end = &adresstable[ADRESS_TABLE_MAX_SIZE];

adresstable_t* find_ID(uint16_t searchID)
{
  adresstable_t *ptr = adresstable;
  for (; ptr < adresstable_end; ptr++)
  {
    if (ptr->id == searchID)
      return ptr;
  }
  return NULL;
}


void add_table (uint16_t x, uint8_t y)
{
  adresstable_t* ptr = find_ID(0);
  if (ptr == NULL)
    return;
  ptr->id = x;
  ptr->adress = y;
  adresstable_size++;
  return;  
}

void remove_table (uint16_t id)
{
  adresstable_t* ptr = find_ID(id);
  if (ptr == NULL)
    return;
  ptr->id = 0;
  ptr->adress = 0;
  adresstable_size--;
  return;  
}

uint8_t getadress_table(uint16_t id)
{
  adresstable_t* ptr = find_ID(id);
  if (ptr == NULL)
    return 255;
  return ptr->adress;
}

Dein Original, mit einer main() dazu, hat 280 Bytes belegt.
Diese Variante ist runter auf 240.
Der Hauptvorteil dürfte darin bestehen, dass in add, remove
und get mit dem retourniertem Pointer nichts mehr gerechnet
werden muss.

Wenn ich mir das Assemblerlisting so ansehe:
Ich glaube nicht, dass da noch viel drinnen ist.
Wenn du noch Platzprobleme hast, musst du woanders mit
der Optimierung weitermachen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
brauchst du die adresstable_size unbedingt?
Wenn du die weg lässt, fallen nochmal 20 Byte weg.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin,
pointer war auch so ein ansatz bei mir. dachte, wenn find_ID schon das 
richtige hat, warum noch einmal neu ranholen.
typedef struct {
        uint16_t id;
        uint8_t adress;
} adresstable_t;

extern adresstable_t adresstable[ADRESS_TABLE_MAX_SIZE];
extern uint8_t adresstable_size;

void add_table (adresstable_t *addr_tab);
void remove_table (uint16_t id);
uint8_t getadress_table(uint16_t id);

#endif //ADRESS_TABLE


adresstable_t adresstable[ADRESS_TABLE_MAX_SIZE];
uint8_t      adresstable_size;

uint8_t find_ID(uint16_t searchID, adresstable_t *a)
{
        uint8_t i;
        adresstable_t *at = adresstable;

        for (i=0;i<ADRESS_TABLE_MAX_SIZE;i++,at++)
        {
                if (at->id == searchID){
                        a = at;
                        return 0;
                }
        }
        return 1;
}


void add_table (adresstable_t *addr_tab)
{
        adresstable_t *a;

        if( ! find_ID(0, a)){
                return;
        }
        a->id = addr_tab->id;
        a->adress = addr_tab->adress;
        adresstable_size++;
        return;
}

void remove_table (uint16_t id)
{
        adresstable_t *a;

        if ( ! find_ID(id,a)){
                a->id = 0;
                a->adress = 0;
                adresstable_size--;
        }
        return;
}

uint8_t getadress_table(uint16_t id)
{
        adresstable_t *a;

        if( ! find_ID(id,a)){
                return a->adress;
        }
        return 255;
}


void main(){
}

bin mir aber nicht 100%ig sicher, ob's das richtige macht :(
falls was als verkehrt erkannt wurde, bin ich nicht böse, kann nur dabei 
lernen :)
bin etwas irritiert, weils mit pointer kleiner geht. nicht, das der 
optimierer da irgednwas wegkickt, was ich übersehen habe.

mit -Os für atmega8
  text    data     bss     dec     hex filename
    144       0       0     144      90 optim_test.o

Size after:
optim_test.elf  :
section    size      addr
.text       238         0
.bss         61   8388704
.stab      2148         0
.stabstr   1931         0
Total      4378


bye kosmo



Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Tipps. Das mit dem Pointer teste ich mal.

Sorry habe auch nicht drangedacht dass da noch #include "main.h" 
drinnenstand.

Melde mich wieder

Mfg
Ulrich

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@kosmonaut

Du willst, dass find() das zweite Argument beim
Aufrufer ändern kann. Also musst du einen Pointer
nehmen, so wie hier:

void foo( int* i )
{
  *i = 5;
}

Wenn du das verallgemeinerst, dann kriegst du für einen
beliebigen Datentyp t

void foo( t * i )
{
  *i = ...
}

Nun ist t bei dir selbst ein Pointerdatentyp. Also setzen
wir mal für t den Datentyp adresstable_t * ein und erhalten:

void foo( adresstable   i )
{
  *i = ...
}

Ergo muss es heissen:
uint8_t find_ID(uint16_t searchID, adresstable_t ** a)
{
  uint8_t i;
  adresstable_t *at = adresstable;

  for (i=0;i<ADRESS_TABLE_MAX_SIZE;i++,at++)
  {
    if (at->id == searchID){
      *a = at;
      return 0;
    }
  }
  return 1;
}

und beim Aufruf dann:
void add_table (adresstable_t *addr_tab)
{
  adresstable_t *a;

  if( ! find_ID(0, &a)){
     return;
  }
  a->id = addr_tab->id;
  a->adress = addr_tab->adress;
  adresstable_size++;
  return;
}

Willkommen bei der 2-Stern Programmierung.

Rein aus Interesse:
Wenn du das korrigierst, bei welcher Größe landest du
dann?

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 2-pointer-programmierung muss nicht unbedingt sein :)

Wenn du das Ergebnis über die Argumentliste zurückgeben
willst, dann führt kein Weg dran vorbei.

Autor: kosmonaut_pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nabend,

unschön, das hier beiträge so mir nichts dir nichts verschwinden :( der 
vorige ist jdf. nicht von mir.


mit 2-pointern verdoppelt sich der speicheraufwand nahezu. 
dementsprechend nicht zu gebrauchen.

Size after:
optim_test.elf  :
section    size      addr
.text       382         0
.bss         61   8388704
.stab      2184         0
.stabstr   1938         0
Total      4565

   text    data     bss     dec     hex filename
    288       0       0     288     120 optim_test.o

selbst wenn man noch etwas unschön rumtrickst ("globaler" 
zwischenpointer, kein temporärer pointer im find_ID) kommt man bzw. ich 
nicht an die 240 bytes von karl heinz heran, limit ist so 270 den dreh.

bye kosmo

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> unschön, das hier beiträge so mir nichts dir nichts verschwinden :(
> der vorige ist jdf. nicht von mir.

Tschuldigung. Das war wahrscheinlich ich.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kosmonaut_pirx wrote:

> mit 2-pointern verdoppelt sich der speicheraufwand nahezu.
> dementsprechend nicht zu gebrauchen.

Das ist schlecht. Ich dachte mir aber schon, dass durch
die zusätzlichen Dereferenzierungen ein nicht unerheblicher
Auswand auftauchen würde. Dazu kommen dann wahrscheinlich
noch ein paar zusätzlich benutzte Register in den Funktionen
die gepusht/gepopt werden müssen.

Das es aber gleich soviel sein würde, hab ich nicht gedacht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.