![]() |
[ASM] Power-Geheimnisse
Eigentlich wollte ich meine Kiste vor dreieinhalb Stunden abstürzen lassen herunterfahren, doch angeregt
![]()
Delphi-Quellcode:
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 :freak: .
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; I
Delphi-Quellcode:
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.
fxch // b, ln 2 * ld a
fmulp st(1), st // ln 2 * ld a * b II
Delphi-Quellcode:
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?
fmulp st(1), st // ld e * ln 2 * ld a * b = ld a * b = x
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 :zwinker: . Hier noch der verbesserte Abschnitt:
Delphi-Quellcode:
Mal sehen, ob der Titel ansprechend genug formuliert ist :mrgreen: .
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 } [1]Ich beherrsche wahrscheinlich sogar CIL besser als Assembler - allein durch den Reflector :duck: . [2]Hoffe mal, das Ausmaß der zitierten Code-Abschnitte liegt noch im (Copyright-)Rahmen. Nacht ihr :hi: . |
Re: [ASM] Power-Geheimnisse
Wo hast du denn das her?
Das ist doch viel kürzer (obs schneller ist, weis ich nicht):
Delphi-Quellcode:
Es basiert eben direkt auf 2^(y*lb(x)). Jetzt ist die Frage, wie lange FYL2X, F2XM1 und FSCALE brauchen.
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 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 :zwinker: Zu Frage II: Weis auch nicht, siehe oben. |
Re: [ASM] Power-Geheimnisse
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
Ohne fxch gelange ich am Ende zu ST0 = a * b, wo ist also der Unterschied :gruebel: ?
// ST0, ST1
// a, b fxch // b, a fmulp st(1), st // b, b * a // pop -> // b * a, |
Re: [ASM] Power-Geheimnisse
Zitat:
Zitat:
|
Re: [ASM] Power-Geheimnisse
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... |
Re: [ASM] Power-Geheimnisse
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz