AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[ASM] Power-Geheimnisse

Ein Thema von Khabarakh · begonnen am 21. Aug 2007 · letzter Beitrag vom 21. Aug 2007
Antwort Antwort
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#1

[ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 02:17
Eigentlich wollte ich meine Kiste vor dreieinhalb Stunden abstürzen lassen herunterfahren, doch angeregt hiervon wollte ich mir einmal kurz die Power-Implementierung der RTL anschauen. Bei "kurz" ist es zwar nicht ganz geblieben, aber ich darf nun behaupten, den Code verstanden zu haben; mit der Zeit bin ich ebenfalls sehr zufrieden, denn es gab da ein kleines Problem: Ich beherrsche kein Wort Assembler [1] . Ausgestattet allein mit dem Verständnis des abstrakten Stack-Typs (soll heißen: Push und Pop ) und einer Webseite über FPU-Instruktionen habe ich mich also debuggend und kommentierend durch den Asm-Code gequält. Das Resultat sieht so aus [2]:
Delphi-Quellcode:
function Power(const Base, Exponent: Extended): Extended;
const
  Max : Double = MaxInt;
var
  IntExp : Integer;
asm
  // Kommentare stellen den FPU-Stack dar: // ST0, ST1
  fld Exponent // b
  [...]//schnipp
  fld Base // a, b
  [...]// schnipp
  fldln2 // ln 2, a, b
  fxch // a, ln 2, b
  fyl2x // ln 2 * ld a, b
  fxch // b, ln 2 * ld a
  fmulp st(1), st // ln 2 * ld a * b
  fldl2e // ld e, ln 2 * ld a * b
  fmulp st(1), st // ld e * ln 2 * ld a * b = ld a * b = x
  fld st(0) // x, x
  frndint // Round(x), x
  fsub st(1), st // Round(x), x - Round(x) // sagen wir einfach Int(x) und Frac(x), auch wenn wir ja auch aufgerundet haben könnten // siehe auch [url]http://t-a-w.blogspot.com/2006/06/docking-assembly.html[/url]
  fxch st(1) // Frac(x), Int(x)
  f2xm1 // 2^Frac(x) - 1, x
  fld1 // 1, 2^Frac(x) - 1, x
  faddp st(1), st // 1 + 2^Frac(x)-1 = 2^Frac(x)
  fscale // 2^Frac(x) * 2^Int(x) = 2^z = 2^(ld a * b) = a^b
end;
Das Ergebnis stimmt, trotzdem müsst ihr mir noch beim Füllen zweier Verständnislücken assistieren: Denn die Funktion zweier Teile habe ich zwar begriffen, doch ... kommen mir sie einfach überflüssig vor .

I
Delphi-Quellcode:
  fxch // b, ln 2 * ld a
  fmulp st(1), st // ln 2 * ld a * b
Bei der Kommentierung dieses Codestücks wurde ich vage an ein Ding namens Kommutativgesetz erinnert... Kurz und knapp: ich sehe keinen Grund, weshalb man die Register vertauschen sollte, wenn man danach sowieso beide in einer Multiplikation kombiniert.

II
fmulp st(1), st // ld e * ln 2 * ld a * b = ld a * b = x Nicht gerade das bekannteste Logarithmusgesetz, aber ihr dürft es gern selbst nachrechnen: log_a(b) * log_b(a) = 1, womit die Umformung im Kommentar gültig ist. Da der Code "einfach nur" 2^(ld a * b) berechnet, muss an dieser Stelle natürlich auch ld a * b herauskommen, das wussten also auch die Entwickler des Codes - doch wozu dann überhaupt das ld e und ln 2, wozu so kompliziert?

Fazit:
Nun denke ich natürlich in beiden Punkten zuerst, dass dies einfach zwei Tricks in diesem Machwerk hochperformaten Assemblers sei, doch irgendetwas lässt mich daran zweifeln... ist wohl die Tatsache, dass meine eigengebaute Power-Routine, die diese zwei Punkte verbessert, 2% schneller ist als das Original .

Hier noch der verbesserte Abschnitt:
Delphi-Quellcode:
  fld1 {   fldln2   }
  fxch // a, >1<, b
  fyl2x // >1< * ld a, b
  {   fxch    // b, ln 2 * ld a   }
  fmulp st(1), st // ld a * b = x
  {  fldl2e  // ld e, ln 2 * ld a * b
      fmulp   st(1), st // ld e * ln 2 * ld a * b = ld a * b   }
Mal sehen, ob der Titel ansprechend genug formuliert ist .

[1]Ich beherrsche wahrscheinlich sogar CIL besser als Assembler - allein durch den Reflector .
[2]Hoffe mal, das Ausmaß der zitierten Code-Abschnitte liegt noch im (Copyright-)Rahmen.

Nacht ihr .
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: [ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 09:38
Wo hast du denn das her?

Das ist doch viel kürzer (obs schneller ist, weis ich nicht):
Delphi-Quellcode:
function power(x,y:extended):extended;
asm
  FLD TBYTE ptr y
  FLD TBYTE ptr x
  FYL2X
  FLD st
  FRNDINT
  FSUB st(1),st
  FXCH
  F2XM1
  FLD1
  FADD
  FSCALE
  FXCH
  FSTP st
end;
Es basiert eben direkt auf 2^(y*lb(x)). Jetzt ist die Frage, wie lange FYL2X, F2XM1 und FSCALE brauchen.
Es sollte aber schneller sein als exp(y*ln(x)) direkt aus der Unit math.

Zu Frage I:
Schau dir mal an wozu das P hinter FMUL da ist

Zu Frage II:
Weis auch nicht, siehe oben.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#3

Re: [ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 12:58
Zitat von sirius:
Wo hast du denn das her?
Aus einer Unit namens "Mathe" oder so ? Turbo Delphi, sollte sich das etwas geändert haben.
Zitat:
Das ist doch viel kürzer (obs schneller ist, weis ich nicht):
Delphi-Quellcode:
function power(x,y:extended):extended;
asm
  FLD TBYTE ptr y
  FLD TBYTE ptr x
  FYL2X
Stimmt, das FLD1 und FMULP hätte ich mir an dieser Stelle sparen und FYL2X (ich liebe diesen Namen) gleich mit x und y füttern können. Mathematik nach 10 Uhr eben . Mit diesen zwei Zeilen weniger wären wir schon bei 4% Vorsprung gegenüber dem Original .
Zitat:
Es basiert eben direkt auf 2^(y*lb(x)). Jetzt ist die Frage, wie lange FYL2X, F2XM1 und FSCALE brauchen.
Es sollte aber schneller sein als exp(y*ln(x)) direkt aus der Unit math.
Jupp, auf Asm-Ebene wird das sicherlich stimmen. Aber im jenem anderen Thread suchten wir ja nach einem möglichst kurzen Power-Hochsprachen-Ersatz ohne Math-Unit. Denn sobald ich dort ein wenig mehr optimieren will, klaue ich doch gleich den Power-Code (nächste Wortspiel ) aus Math mit seinen weiteren Optimierungen (hätte nicht gedacht, dass Power wirklich eine Schleife benutzt).
Zitat:
Zu Frage I:
Schau dir mal an wozu das P hinter FMUL da ist
Zitat:
Multiply ST(i) by ST(0), store result in ST(i), and pop the register stack
Soll heißen, es passiert folgendes:
Delphi-Quellcode:
// ST0, ST1
// a, b
fxch
// b, a
fmulp st(1), st
// b, b * a
// pop ->
// b * a,
Ohne fxch gelange ich am Ende zu ST0 = a * b, wo ist also der Unterschied ?
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: [ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 13:12
Zitat von Khabarakh:
Soll heißen, es passiert folgendes:
Delphi-Quellcode:
// ST0, ST1
// a, b
fxch
// b, a
fmulp st(1), st
// b, b * a
// pop ->
// b * a,
Ohne fxch gelange ich am Ende zu ST0 = a * b, wo ist also der Unterschied ?
Ja mit st(1) macht es nicht wirklich Sinn

Zitat:
Aus einer Unit namens "Mathe" oder so ? Turbo Delphi, sollte sich das etwas geändert haben.
Aha, da haben sie also von D7 auf D2006 was geändert.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: [ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 13:38
Auch wenn es komisch und unsinnig aussieht - das macht Sinn, dieses FXCHG und dann FMULP st(1),st

Überlege mal, was wäre, wenn das FXCHG nicht da wäre und was man alles machen müßte, um am Ende das gleiche Ergebnis und einen sauberen FPU-Stack zu haben...
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: [ASM] Power-Geheimnisse

  Alt 21. Aug 2007, 13:57
Zitat von OlafSt:
Auch wenn es komisch und unsinnig aussieht - das macht Sinn, dieses FXCHG und dann FMULP st(1),st

Überlege mal, was wäre, wenn das FXCHG nicht da wäre und was man alles machen müßte, um am Ende das gleiche Ergebnis und einen sauberen FPU-Stack zu haben...
Man macht eben nur FMULP ohne FXCH und kommt aufs selbe Ergebnis in der FPU
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz