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?
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
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.
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.
brauchst du die adresstable_size unbedingt? Wenn du die weg lässt, fallen nochmal 20 Byte weg.
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
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
@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?
> 2-pointer-programmierung muss nicht unbedingt sein :)
Wenn du das Ergebnis über die Argumentliste zurückgeben
willst, dann führt kein Weg dran vorbei.
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
> unschön, das hier beiträge so mir nichts dir nichts verschwinden :( > der vorige ist jdf. nicht von mir. Tschuldigung. Das war wahrscheinlich ich.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.