
Zitat von
cumi
Nun, also, wenn ich eine saturierung selbst implementieren will, wie gehe ich dann vor?
Genau wie du es geschreiben hast.
Wenn es optimal sein soll nimmst du Assembler, das spart pro Multiplikation ein paar Takte/Instruktionen; bei signed saturation wohl noch mehr.
Code:
#define UCHAR_MAX 255
#define CR "\n"
#define CR_TAB CR"\t"
#define UMUL8_SAT(a,b) \
({ \
unsigned char __tmp; \
asm volatile ( \
"mul %1, %2" CR_TAB \
"mov %0, r0" CR_TAB \
"tst r1" CR_TAB \
"breq 0f" CR_TAB \
"ldi %0, %3" CR_TAB \
"clr r1" CR \
"0:" \
: "=d" (__tmp) \
: "r" (a), "r" (b), "i" (UCHAR_MAX)); \
__tmp; \
})
Je nachdem, welche Werte du hast, kann es günstiger sein, statt immer wieder zu saturieren eine Fixpunktarithmetik auf normierten Werten zu verwenden, z.B. eine 8.8 Aritmetik (8 Bit vorm Komma, 8 dahinter). Wenn die Werte zB immer im Intervall [quote=cumi]inge auch eine 0.16 Arithmetik...
Kommt drauf an, welche Genauigkeit du brauchst und welchen Aufwand du für welche Effizienz betreiben willst.

Zitat von
cumi
Äh und noch zum inlining. [...]
Ich dachte, mit inline könne man die Ausführgeschwindigkeit des Codes steigern auf kosten der Compilatgrösse. Stimmt das nicht so? Oder in welchen Fällen stimmt das so?
Falls eine Funktion geinlint wird, dann wird anstatt Parameteraufbereitung - Paramerübergabe - Aufruf - Returnübergabe - Parameternachbereitung das Stückchen Syntaxbaum, welches die inline-Funktion darstellt, an der Stelle ihres Aufrufs in den Syntaxbaum des Aufrufers reinkopiert. Lax gesprochen.
Da der Code der Funktion bekannt ist und die Funktion nicht mehr als Blackbox anzusehen ist, ermöglich das Optimierungen, insbesondere bei der Registerverwendung. Natürlich ist vom Inlining nicht nur der Code der Funktion selbst betrofen, sondern auch der Code des Aufrufers. Inlining ist ja nich lokal auf die Aufrufstelle beschränkt und beeinfluus auch die Registerallokierung des Aufrufers.
Ist nun die i-Funktion komplex und braucht viele Register, dann kann das dazu führen, daß für den Aufrufer ein Frame angelegt werden muß und lokale Variablen nicht mehr in Register leben, sondern im Frame der Funktion. Das ist ungünstig, denn ein RAM-Zugriff ist deutlich ineffizienter als Werte in GPRs zu halten. Die Slot-Zugriffe machen den Code langsamer und breiter.
Die Intention von "inline" ist, in eine bestimmt Richtung zu optimieren. Wenn einem die Effizienz von optimiertem gcc-Code nicht genügt (und die ist schon beachtlich gut), dann muss man sehr genau wissen, was man tut, um weiter in Richtung Optimum zu kommen. Ansonsten geht das ruck-zuck nach hinten los. Je näher man schon am Optimum ist, desto mehr Wege führen eben wieder vom Optimum weg...
[schild=18 fontcolor=000000]Mühsam ernährt sich das Eichhörnchen[/schild]
GCC hat intern Heuristiken, anhand derer bestimmt wird, ob eine Funktion es würdig ist, geinlinet zu werden. Dabei können auch Funktionen geinlint werden, die nicht mit "inlinie" gekennzeichnet sein, oder solche mit "inline" werden davon ausgenommen, AFAIK. Das statisch zu analysieren wäre viel zu aufwändig und spekulatives Compilieren wird nicht gemacht, da das ebenfalls sehr (zeit)aufwändig wäre.

Zitat von
cumi
Und noch zu den Verzeichnissen vom GCC. Ok, das mag ja seinen Sinn haben. Ich bin da nur geich einwenig erschrocken und habe mich dann entschlossen eine komplett eigene Bibliothek anzufertigen, damit ich verstehe, mit was ich programmiere. Ich habe auch beim programmieren furchtbar Angst vor dem Unbekannten

, welches im Hintergrund für mich nicht nachvollziehbare Dinge tut. Die IO-Definitionen habe ich zu einem grossen Teil aus der AVR-Lib-C rauskopiert.
Verstehen zu wollen, was man tut, ist heutzutage eine aussterbende Tugend...
GCC ist ein Moloch. Rund 4.000.000 Zeilen Quellcode verteilen sich auf über 15.000 Dateien. Da sind weder die libc noch die binutils (Assembler, Linker, Debugger, ...) mitgezählt.
Zweifellos schleppt GCC viele Altlasten mit sich herum. Seine Designpattern gehen auf die 80-er Jahre zurück. Solch ein Schlachtschiff komplett umzubauen und zig Mannjahre drauf zu verwenden, ohne was an Funktionalität zu gewinnen, wurde bislang nicht angegangen. Ohnehin gibt es nur eine handvoll Leute auf diesem Planeten, die *wirklich* durchblicken, was in den Gedärmen von GCC wirklich geschieht. Neuerungen finden eher im Bereich "Effizienzsteigerung" statt, im Bereich "Redesign" nur sehr zurückhaltend.
IMHO ist C auch keine angemessene Sprache, um einen Compiler wie GCC zu programmieren. Man müsste erst mal eine adäquate Sprache entwickeln...
Lesezeichen