- fchao-Sinus-Wechselrichter AliExpress         
Seite 3 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 21 bis 30 von 31

Thema: Festpunktarithmetik

  1. #21
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    58
    Beiträge
    1.195
    Anzeige

    E-Bike
    Ich hoffe, ich verwirre dich nicht zu sehr Razz
    Au contraire!
    Ich lerne einiges dazu (auch Dank Deines schönen Inline-Assembler Artikels im Wiki).

    Das mit dem Aufruf aus dem inline Assembler kannte ich noch nicht. Sehr chic! Damit die alten Ideen nicht verloren gehen packe ich das wahrscheinlich in ein neues File.

    Ich tauche da zwar noch selber ein, aber auf die Schnelle: Wozu dient das r1 = 0 hinter r27:r26 = sat(r1:r0), r1=0 ?

  2. #22
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von ogni42
    Das mit dem Aufruf aus dem inline Assembler kannte ich noch nicht. Sehr chic!
    Ein solcher Funktionsaufruf innerhalb von asm ist transparent für gcc, d.g. er sieht die Funktion nicht, da sie ja nicht von C-Ebene aufgerufen wird. saturate16 von C aus aufzurufen ist sogar ein schwerer Fehler (überleg dir, warum).

    Das unschöne an der Sache ist, daß man genau festlegen muss, in welchem Register der Wert ankommt, hier X. Dazu braucht man eine Registerklasse (also Constraint, hier "x"). Für 16-Bit-Werte ist das ok. Wenn Result allerdings nur ein 8-Bit-Wert wäre, dann muss im aufrufenden asm r27 geclobberd werden, damit GCC nicht auf die Idee kommt, result nach r27 zu reloaden! Man hat dann ein Register für nix verbraucht.

    Für 8-Bit-Werte lohnt sich sowas hier vermutlich nicht, aber bei 16-Bit-Werten und vielen Aufrufen dürfte es zu einem deutlichen Code-Schrumpf führen. Selbst dann, wenn mehrere 16-Bit sat-Versionen gebraucht werden.

    Zitat Zitat von ogni42
    Wozu dient das r1 = 0 hinter r27:r26 = sat(r1:r0), r1=0 ?
    Ist nur ein Kommentar, der sowohl auf C als auch auf asm Ebene sichtbar ist.

    Falls es um den Code geht: In __zero_reg__ (r1) steht fast immer eine 0. Daher zB auch das clr __zero_reg__ in ISR-Prologues.

    In größeren Funktionen ist es oft praktisch, die Konstante 0 zur Verfügung zu haben. Daher ist laut ABI (application binary interface) von avr-gcc in diesem Register immer die 0. Dieses Register ist (ebenso wie r0) ein fixed Register, daß heißt, GCC hat keine Vorstellung von diesen Registern und wird sie nie verwenden.

    Das hört sich jetzt seltsam an, weil r1 und r0 in avr-gcc ja Verwendung finden. Allerdings tauchen diese Register in avr-gcc nur als Strings auf (ähnlich wie inline asm in C nur ein String ist) und GCC hat keine interne Vorstellung von den Registern.

    Wenn also r1 einen anderen Wert bekommt (zB durch eine MUL), dann muss die Insn (oder inline asm), die das Register verändert hat, wieder den Wert 0 hineinschreiben. Das ist der Grund dafür, daß diese Insns als asm Befehl immer auch ein cli r1 enthalten und ein clobbern dieses Registers nicht den gewünschten Effekt zeigt, wie am Ende des Abschnitts

    https://www.roboternetz.de/wissen/in...r-gcc#Clobbers

    beschrieben.
    Disclaimer: none. Sue me.

  3. #23
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    58
    Beiträge
    1.195
    Falls es um den Code geht: In __zero_reg__ (r1) steht fast immer eine 0. Daher zB auch das clr __zero_reg__ in ISR-Prologues.
    Das ist schon klar, aber: Nach dem Aufruf von muls steht in r1 das Ergebnis der Operation und wird ja auch so in saturate16 verwendet. Ist dann das r1=0 nicht irreführend?

  4. #24
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von ogni42
    aber: Nach dem Aufruf von muls steht in r1 das Ergebnis der Operation und wird ja auch so in saturate16 verwendet. Ist dann das r1=0 nicht irreführend?
    In C sähe das ja so aus:
    Code:
    foo_t fmul (foo_t a, foo_t b)
    {
        r1_r0 = a*b;
        v = (|a*b| > 1); // oder so
        saturate16 ();
        return r27_r26;
    }
    
    // Inputs: r1_r0 und Overflow (v-Flag)
    void saturate16 (void)
    {
        r27_r26 = sat16 (r0_r1, v);
        r1 = 0;
    }
    saturate16 saturiert also nicht nur, sondern löscht zusätzlich r1. Dadurch entfällt das clr r1 im inline asm (wird kürzer) und daher der Kommentar r1=0 an saturate 16.

    BTW: Wieso kann die Multiplikation überhaupt überlaufen?

    Wie ist da überhaupt die Darstellung der Fraction? Im Komplement oder als sign(a) : abs (a) ? Vermutlich ersteres, sonst wäre Strichrechnung ja recht aufwändig...
    Disclaimer: none. Sue me.

  5. #25
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    58
    Beiträge
    1.195
    Ah, ok.

    Die Multiplikation kann nicht überlaufen. Die Sättigung ist ja nur bei den fadd, fsub und fmac Routinen drin. Die Darstellung ist im Comp_2.

    Solche Ops kannte ich bisher nur von DSPs und dem MA16 (systolisches Feld). Bei vielen DSPs und dem MA16 ist die Sättigung für fmac aber IIRC in Hardware eingebaut.

  6. #26
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Und wozu das alles? Für PID-Regler oder so? Oder sin/cos?

    Nette Spielwiese übrigens, hier der logarithmus dualis:

    Code:
    static inline uint8_t log_2 (uint8_t);
    
    // log(x) / log(2) mit 1 <= x < 2
    uint8_t log_2 (uint8_t x)
    {
        uint8_t log, cnt;
        asm volatile ("; %[log] = log_2 (%[x]) "       "\n\t"
            "ldi     %[cnt], 7"                        "\n\t"
            "clr     %[log]"                           "\n"
            "0:"                                       "\t"
            "lsl     %[log]"                           "\n\t"          
            "fmul    %[x], %[x]"                       "\n\t"
            "brcc    1f"                               "\n\t"
            "ror     r1"                               "\n\t"
            "inc     %[log]"                           "\n"
            "1:"                                       "\t"
            "mov     %[x], r1"                         "\n\t"
            "dec     %[cnt]"                           "\n\t"
            "brne    0b"                               "\n\t"
            "clr     __zero_reg__"
            : [log] "=r" (log), [x] "=a" (x), [cnt] "=d" (cnt)
            : "1" (x)
         );
    
        return log;
    }
    Disclaimer: none. Sue me.

  7. #27
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    58
    Beiträge
    1.195
    Bei mir im Moment im Wesentlichen für künstliche Neuronale Netze. Kann man aber auch für Filteroperationen in der Bildverarbeitung, FFT etc. gut einsetzen.

    Schicke Lösung für den Log.

  8. #28
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von ogni42
    künstliche Neuronale Netze
    Ah. Kenn ich nur vom Hörensagen. Ich dachte, Neuronale Netze seien der Natur nachempfunden? Dort kann ich mir so harte Sachen wie einfach einen Wert abschneiden (Saturierung, clipping) schlecht vorstellen.

    Wenn zwei Nervenzellen zB ihre Signale addieren, dann wäre folgendes doch viel "natürlicher":

    Code:
    +: [0,1] x [0,1] -> [0,1]
    a + b := 1 - (1-a)*(1-b)
    Für keine a, b ist das fast das gleiche wie a+b. Für größere a, b geht das schön langsam in die Sättigung und bleibt immer in [0,1]. Es ist monoton in beiden Argumenten, symmetrisch, assoziativ(!), glatt (beliebig oft diff'bar) und leicht zu berechnen.

    Zudem geht keine Information verloren. Bei einem saturierten + kann es sein, daß a+b=a+c gilt aber daraus folgt *nicht*, daß b=c ist. Für das weiche + ist das der Fall, zumindest wenn a im Innern des Intervalls ist.

    Man kann also sogar Inverse (also -) definieren und es gibt ein eindeutiges Neutrales (die 0), was bei einer normalen Saturierung nicht geht. Wenn der Wert oben angeschlagen ist, dann gibt es kein Zurück mehr...
    Disclaimer: none. Sue me.

  9. #29
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    58
    Beiträge
    1.195
    Die Idee hinter den meisten künstlichen Neuronalen Netzen ist, dass die Ausgabe von Neuronen mit einem synaptischen Gewicht multipliziert werden (entsprechend der Stärke der Verbindung zwischen zwei Nervenzellen). Die Summe aller Ausgaben der Vorgängerneuronen multipliziert mit den synaptischen Gewichten ist die Eingabeaktivierung des aktuellen Neurons. Das läßt sich sehr schön auf eine Matrixmultiplikation abbilden (nxm, mit n=Anzahl Neuronen der Schicht l-1 und m=Anz. N. der Schicht l) Für ein Neuron ergibt sich dessen Ausgabe aus der Stärke der Aktivierung am Eingang und einer Aktivierungsfunktion (z.B. tanh).

    Ab einem gewissen Wert (positiv oder negativ) verändert sich die Aktivierung am Ausgang nur noch marginal. Daher funktioniert die Sättigung sehr gut.

    Deine Formel setzt stets positive Aktivierungen voraus. Es gibt aber auch negative (Inhibition). Da fände sich vielleicht eine ähnliche Formel die [-1, 1[ x [-1, 1[ -> [-1, 1[ bewirkt, aber in der Regel reicht die einfache Sättigung aus (und ist schneller zu berechnen).

  10. #30
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von ogni42
    Deine Formel setzt stets positive Aktivierungen voraus. Es gibt aber auch negative (Inhibition). Da fände sich vielleicht eine ähnliche Formel die [-1, 1[ x [-1, 1[ -> [-1, 1[ bewirkt, aber in der Regel reicht die einfache Sättigung aus (und ist schneller zu berechnen).
    Ja stimmt. Das additiv Inverse zu a ist a/(1-a) und das ist kleiner 0, so daß man die negativen Zahlen hinzunehmen müsste.

    Em Endeffekt ist es ja nur eine Transformation von [0, oo] auf [0, 1] und wäre dann eine Trafo (bzw. Isomorphismus) von R nach [-oo, 1].

    Ich will ja keine neue Theorie aufstellen (wenn, wär sie nicht neu und gibt's bestimmt schon). Wollte einfach mal ein bisschen nachdenken drüber

    Ganz nett an [0,1] auch, daß man da (zumindest einen Teil) der Bool'schen Algebra hat: Mit

    a AND b = ab
    a OR b = a+b-ab
    NOT a = 1-a

    Hat man zB die De-Morgan'schen Regeln. Ist vielleicht eher was für die Fuzzi-Leute...

    Mit tanh ist es natürlich viel simpler und man hat die "weiche" Sättigung unanhängig von der eigentlichen Operation.
    Disclaimer: none. Sue me.

Seite 3 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen