Da im letzten Thread ein paar super Hinweise kamen hat es mich grad
motiviert noch eine Frage zu stellen:)
Manche Compiler können es wahrscheinlich schon von Haus aus - aber eben
nicht alle.
Ich möchte den Absolutbetrag einer int32_t möglichst schnell, aber ohne
Assembler, und mit Standard-C berechnen (Also keine compilerspezifischen
Code, der dann nicht portierbar ist..).
Meine Lösungen sehen momentan so aus:
1
// Lösung 1:
2
int32_tlabs(int32_tx)
3
{
4
if(x<0)return-x;
5
elsereturnx;
6
}
7
8
// Lösung 2:
9
#define labs(x) ((x) >= 0 ? (x) : -(x))
Geht es noch schneller? (z.B. Abfrage des sign-bits durch
Und-Verknüfung..)
Andreas schrieb:> Meine Lösungen sehen momentan so aus:
Passt. Lesbar, wartbar, portierbar.
> Geht es noch schneller?
Hast du gemessen dass es zu langsam ist?
Glaub ich dir nicht, Compilerbauer sind auch nicht blöd :-)
@Heinz: Das funktioniert eben nicht generell bei allen Compiler
Manche unterstützen nur 16-bit Variablen.
@Stefan:
Die Zweierkomplementbildung ist mir schon klar. Ich habe mir aber
gedacht, es könnte Kompatiblitätsprobleme geben, da die Bytes nicht in
allen Betriebssystemen gleich angeordnet sind. Vielleicht ist es aber
nur eine Befürchtung:)
@Floh: Erst jetzt gesehen)
Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen.
Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier
kommen ja immer wieder super Anregungen.
Andreas schrieb:> Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen.> Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier> kommen ja immer wieder super Anregungen.
Lerneffekt?
Überlass das dem Compiler bzw. den Funktionen die du in der Runtime
Library mitbekommen hast.
Sich da über 2-er Komplement den Kopf zu zerbrechen lohnt nicht.
So wie es sich meistens nicht lohnt, über derartige Klein-Klein
Optimierung den Kopf zu zerbrechen. Benutze die richtigen Datentypen,
benutze gute Algorithmen und den Rest überlass dem Compiler. Denn wie
sagte schon Floh: Compilerbauer sind auch keine Trottel.
Es bringt nix, einen Bubblesort auf den letzten Taktzyklus hin zu
optimieren, wenn ihn ein unoptimierter Quick-Sort aus dem Stand schlägt.
Andreas schrieb:> @Heinz: Das funktioniert eben nicht generell bei allen Compiler> Manche unterstützen nur 16-bit Variablen.
Ist mir neu! Danke für den Hinweis.
@Helfer: Ja, stimmt, beim kleinsten Wert hätte man ein Problem
@Karl Heinz: Ja, das stimmt schon was du sagst, das
Optimierungspotenzial liegt ganz sicher wo anderst. Eben auch in
durchdachten Strukturen:):)
Trotzdem: Ineffiziente Elementarfunktion können bei häufigem Aufruf auch
ins Gewicht fallen. Ebens ist auch interessant, wie andere elementare
Funktionen umsetzen. ..und eine Info habe ich ja nun wieder gewonnen
nämlich dass die aktuelle Variante einen guten Weg darstellt:)
Andreas schrieb:> @Floh: Erst jetzt gesehen)>> Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen.> Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier> kommen ja immer wieder super Anregungen.
Könntest du mal ein Assembler-Listing davon übersetzen?
19 Instruktionen kommt mir ziemlich viel vor, eventuell stecken da noch
Instruktionen zum Laden und Speichern zwischen Register und RAM drin?
@A.K. Nein, die Optimierung ist vollständig ausgeschaltet.
Wieviel man aber bei maximaler Speedoptimierung herausholt, das kann ich
nicht ermitteln. Ich glaube aber, es macht noch einiges aus.
Andreas schrieb:> @A.K. Nein, die Optimierung ist vollständig ausgeschaltet.
Yep, das war erkennbar. Folglich ist es völlig sinnlos, wie hier gezeigt
die Befehle zu zählen.
Andreas schrieb:> @Heinz: Das funktioniert eben nicht generell bei allen Compiler> Manche unterstützen nur 16-bit Variablen.>> @Stefan:> Die Zweierkomplementbildung ist mir schon klar. Ich habe mir aber> gedacht, es könnte Kompatiblitätsprobleme geben, da die Bytes nicht in> allen Betriebssystemen gleich angeordnet sind.
C macht keine Angabe darüber, wie negative Zahlen dargestellt werden!
Zweierkomplement ist üblich, aber nicht zwingend -- was auch der Grund
dafür ist, daß signed-Überlauf in C undefined ist und Compiler das
ausnutzen können.
Mit der if/else vanilla-Variante bist du auf der sicheren Seite; Problem
stellt lediglich INT32_MIN dar, da im Zweierkomplement -INT32_MIN nicht
darstellbar ist und auf INT32_MIN abgebildet wird. Will man das abfangen
(etwa durch Abbildung auf INT32_MAX), dann muss das vor der
Betragsbildung geschehen! Versucht man es danach, darf der Compiler
verwenden, daß signed-Überlauf undefined ist!