Forum: Compiler & IDEs Benötige Hilfe bei Optmierung


von Ulrich (Gast)


Angehängte Dateien:

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?

von Stefan (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Karl H. (kbuchegg)


Lesenswert?

So hab ich bei -Os noch ein bischen was herausgeholt:
1
adresstable_t* adresstable_end = &adresstable[ADRESS_TABLE_MAX_SIZE];
2
3
adresstable_t* find_ID(uint16_t searchID)
4
{
5
  adresstable_t *ptr = adresstable;
6
  for (; ptr < adresstable_end; ptr++)
7
  {
8
    if (ptr->id == searchID)
9
      return ptr;
10
  }
11
  return NULL;
12
}
13
14
15
void add_table (uint16_t x, uint8_t y)
16
{
17
  adresstable_t* ptr = find_ID(0);
18
  if (ptr == NULL)
19
    return;
20
  ptr->id = x;
21
  ptr->adress = y;
22
  adresstable_size++;
23
  return;  
24
}
25
26
void remove_table (uint16_t id)
27
{
28
  adresstable_t* ptr = find_ID(id);
29
  if (ptr == NULL)
30
    return;
31
  ptr->id = 0;
32
  ptr->adress = 0;
33
  adresstable_size--;
34
  return;  
35
}
36
37
uint8_t getadress_table(uint16_t id)
38
{
39
  adresstable_t* ptr = find_ID(id);
40
  if (ptr == NULL)
41
    return 255;
42
  return ptr->adress;
43
}

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.

von Karl H. (kbuchegg)


Lesenswert?

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

von kosmonaut pirx (Gast)


Lesenswert?

moin,
pointer war auch so ein ansatz bei mir. dachte, wenn find_ID schon das 
richtige hat, warum noch einmal neu ranholen.
1
typedef struct {
2
        uint16_t id;
3
        uint8_t adress;
4
} adresstable_t;
5
6
extern adresstable_t adresstable[ADRESS_TABLE_MAX_SIZE];
7
extern uint8_t adresstable_size;
8
9
void add_table (adresstable_t *addr_tab);
10
void remove_table (uint16_t id);
11
uint8_t getadress_table(uint16_t id);
12
13
#endif //ADRESS_TABLE
14
15
16
adresstable_t adresstable[ADRESS_TABLE_MAX_SIZE];
17
uint8_t      adresstable_size;
18
19
uint8_t find_ID(uint16_t searchID, adresstable_t *a)
20
{
21
        uint8_t i;
22
        adresstable_t *at = adresstable;
23
24
        for (i=0;i<ADRESS_TABLE_MAX_SIZE;i++,at++)
25
        {
26
                if (at->id == searchID){
27
                        a = at;
28
                        return 0;
29
                }
30
        }
31
        return 1;
32
}
33
34
35
void add_table (adresstable_t *addr_tab)
36
{
37
        adresstable_t *a;
38
39
        if( ! find_ID(0, a)){
40
                return;
41
        }
42
        a->id = addr_tab->id;
43
        a->adress = addr_tab->adress;
44
        adresstable_size++;
45
        return;
46
}
47
48
void remove_table (uint16_t id)
49
{
50
        adresstable_t *a;
51
52
        if ( ! find_ID(id,a)){
53
                a->id = 0;
54
                a->adress = 0;
55
                adresstable_size--;
56
        }
57
        return;
58
}
59
60
uint8_t getadress_table(uint16_t id)
61
{
62
        adresstable_t *a;
63
64
        if( ! find_ID(id,a)){
65
                return a->adress;
66
        }
67
        return 255;
68
}
69
70
71
void main(){
72
}

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



von Ulrich (Gast)


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

von Karl H. (kbuchegg)


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:
1
uint8_t find_ID(uint16_t searchID, adresstable_t ** a)
2
{
3
  uint8_t i;
4
  adresstable_t *at = adresstable;
5
6
  for (i=0;i<ADRESS_TABLE_MAX_SIZE;i++,at++)
7
  {
8
    if (at->id == searchID){
9
      *a = at;
10
      return 0;
11
    }
12
  }
13
  return 1;
14
}

und beim Aufruf dann:
1
void add_table (adresstable_t *addr_tab)
2
{
3
  adresstable_t *a;
4
5
  if( ! find_ID(0, &a)){
6
     return;
7
  }
8
  a->id = addr_tab->id;
9
  a->adress = addr_tab->adress;
10
  adresstable_size++;
11
  return;
12
}

Willkommen bei der 2-Stern Programmierung.

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

von kosmonaut pirx (Gast)


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.

von kosmonaut_pirx (Gast)


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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

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.