![]() |
Re: Function für Vorzeichen?
Zitat:
|
Re: Function für Vorzeichen?
Es kommt darauf an, wie oft das aufgerufen wird. Du solltest mal die abs()-Funktion der Math-Unit sehen. Die ist vielleicht optimiert, sag ich dir.
|
Re: Function für Vorzeichen?
Zitat:
greetz Mike |
Re: Function für Vorzeichen?
Das sehe ich anders. Bei so grundlegenden, also so eigentlich primitiven Funktionen jedenfalls. Bei einer sehr speziellen Funktion, die selten aufgerufen wird, kann das wieder anders aussehen. Aber wenn mein Code oft wiederverwendet wird, optimiere ich ihn lieber.
Und so ein if kann den Prozessor nunmal ordentlich ausbremsen, daher vermeide ich es nunmal gerne. |
Re: Function für Vorzeichen?
Hallo :hi:
hab die Diskussion hier von anfang an verfolgt. Warum? Weils IMHO sehr interessant is, wie man doch so ne einfache Funktion auf unterschiedlichste Art schreiben kann. Aus der ganzen Optimiererei lernt man doch so einiges... Zitat:
Zitat:
In diesem Fall is aber IMHO ne lesbare Version besser. Der Quotent Code-Kommentar / Geschwindigkeit is nämlich annähernd konstant... Und ich hab, wenns auf n paar Mikrosekunden hin oder her nicht ankommt lesbaren code lieber, als schnellen... mfg Christian |
Re: Function für Vorzeichen?
Zitat:
Wenn Du schon bei "eigentlich pimitiven" Funktionen lieber optimierst, warum machst Du das denn nicht konsequent ? Ich hab mal Deinen Vorschlag und zwei Alternativen getestet. Für jeweils 1000000 Durchläufe habe ich gemessen (P4, 2.66 GHz) Dein Vorschlag = 38.7 ms Alternative 1 = 16.1 ms Alternative 2 = 5.6 ms, also knapp 7 mal so schnell wie Deine Version.... Ich denke, daß ca. sieben mal so schnell eine Assemblerversion rechtfertigt. Und warum ist Deine Funktion so bummelig ? Schau Dir das ganze doch mal im Debugger in der CPU-Ansicht an. Du übergibst 2 Extended Werte als Const Parameter (weil du meints das bringe Vorteile ?). Bringt aber nichts. Es werden nicht etwa Pointer in Registern übergeben sondern die Parameter werden auf dem Stack übergeben. Tatsächlich passiert in etwa folgendes. 1) a und b werden auf den Stack gelegt. Dann wird Deine Funktion aufgerufen. 2) das "result:=a" legt a dann noch einmal auf den Stack. 3) dann kommt die Berechnung des Vorzeichens, was auch nicht ganz so schnell abläuft. 4) abschließend wird result vom Stack in die FPU geladen. (Extended Werte werden im TOS zurück gegeben.) 5) und wird dann nach Rückkehr aus Deiner Funktion in c gestellt. Und warum sind die Alternativen so schnell ? Schaue es Dir mal im Debugger an.... Bei allen Versionen ist übrigens, wenn a=0 und b negativ ist, das Resultat -0 (ja, die FPU unterscheidet zwischen positiver 0 und negativer 0). Ob das bei irgenwelchen Berechnungen Auswirkungen hat, ist mir nicht bekannt. Alternative 1
Delphi-Quellcode:
Das "if" und der ev. damit verbundene Sprung kostet übrigens so gut wie gar nichts.
PROCEDURE xSignMultiply(var a,b,c:extended);
asm fld TByte [eax] test Byte [edx+9],$80 je @1 fchs @1: fstp TByte [ecx] end; Alternative 2
Delphi-Quellcode:
Der Vollständigkeit wegen Dein Vorschlag
PROCEDURE ySignMultiply(var a,b,c:extended);
asm push ebx mov ebx,[eax] mov [ecx],ebx mov ebx,[eax+4] mov [ecx+4],ebx mov ax,[eax+8] mov bx,[edx+8] and bx,$8000 xor ax,bx mov [ecx+8],ax pop ebx end;
Delphi-Quellcode:
Und mit folgender Prozedur hab ich die Zeiten gemessen.
function signmultiply(const a, b: Extended): Extended;
begin result:=a; PByte(Integer(@result)+9)^:=PByte(Integer(@result)+9)^ xor (PByte(Integer(@b)+9)^ and (1 shl 7)); end;
Delphi-Quellcode:
PROCEDURE TMain.Test;
var a,b,c:extended; i:integer; q0,q1,q2,q3:int64; s1,s2,s3:string; begin a:=-200; b:=-300; queryperformancecounter(q0); for i:=1 to 1000000 do c:=SignMultiply(a,b); queryperformancecounter(q1); dec(q1,q0); queryperformancecounter(q0); for i:=1 to 1000000 do xSignMultiply(a,b,c); queryperformancecounter(q2); dec(q2,q0); queryperformancecounter(q0); for i:=1 to 1000000 do ySignMultiply(a,b,c); queryperformancecounter(q3); dec(q3,q0); QueryPerformanceFrequency(q0); str((q1/q0):0:6,s1); str((q2/q0):0:6,s2); str((q3/q0):0:6,s3); ShowMessage(s1+#13+s2+#13+s3); end; |
Re: Function für Vorzeichen?
Normalerweise hätte ich das mit Assembler gemacht, aber ich kenne mich dafür noch nicht gut genug mit der FPU aus.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:37 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 by Thomas Breitkreuz