Benötige Hilfe bei Optmierung

Gast #495778
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?
Angehängte Dateien:
Gast #495807
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
Moderator Persönliche Seite #495815
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.
#495863
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.
Gast #495881
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


#495952
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?
Gast #496030
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
#496044
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren