AGB  ·  Datenschutz  ·  Impressum  







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

Function für Vorzeichen?

Ein Thema von Cöster · begonnen am 8. Sep 2006 · letzter Beitrag vom 10. Sep 2006
Antwort Antwort
Seite 6 von 6   « Erste     456   
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.735 Beiträge
 
Delphi 2007 Professional
 
#51

Re: Function für Vorzeichen?

  Alt 9. Sep 2006, 23:40
Zitat von 3_of_8:
Das geht schneller:

Delphi-Quellcode:
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;
c:=signmultiply(a, b) macht in etwa das: if b<0 then c:=-a else c:=a;
Ihr habt doch alle nen Schlag. Wer will denn so nen Code haben, um vielleicht drei Nanosekunden zu sparen?
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#52

Re: Function für Vorzeichen?

  Alt 9. Sep 2006, 23:41
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.
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#53

Re: Function für Vorzeichen?

  Alt 9. Sep 2006, 23:50
Zitat von 3_of_8:
Es kommt darauf an, wie oft das aufgerufen wird.
Wenn bei einer Prozedur der Aufruf fast gleich lang braucht wie die Ausfuerhung des Inhalt selbst, dann sind solche Optimierungen eher zweitrangig. Und wenn eine Funktion um 1% schneller ist als eine andere, dann spielt es keine Rolle, wie oft sie aufgerufen wird - ich spare mir immer nur 1% der Zeit. Und nachdem wir nicht mehr um 1970 leben, als CPU-Zeit mit Barem bezahlt wurde, wuerde ich bei so geringen Laufzeitunterschieden eher auf Lesbarkeit setzen.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#54

Re: Function für Vorzeichen?

  Alt 9. Sep 2006, 23:53
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.
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#55

Re: Function für Vorzeichen?

  Alt 10. Sep 2006, 10:31
Hallo
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 von 3_of_8:
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.
IMHO bringt Optimierung nur was, wenn die Funktion in einer langen Schleife aufgerufen wird. Ansonsten is das mehr lernen, wie man mit Algorithmen umgeht...

Zitat:
Und so ein if kann den Prozessor nunmal ordentlich ausbremsen, daher vermeide ich es nunmal gerne.
Echtzeitprogrammierung wär was für dich. Da gehts nämlcih wirklich um jede Mikrosekunde. Ergo: Möglichst keine Sprünge, schon gar keine bedingten. Divisionen vermeiden. Viel rumschieben, ... N DSP is eben etwas langsamer als ne PC CPU. Und, wenn das ganze auch noch alle paarhundert *Mikro*sekunden passieren soll, ...

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
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.041 Beiträge
 
Delphi XE2 Professional
 
#56

Re: Function für Vorzeichen?

  Alt 10. Sep 2006, 12:09
Zitat von 3_of_8:
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.
@3_of_8 :

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:
PROCEDURE xSignMultiply(var a,b,c:extended);
asm
      fld TByte [eax]
      test Byte [edx+9],$80
      je @1
      fchs
@1: fstp TByte [ecx]
end;
Das "if" und der ev. damit verbundene Sprung kostet übrigens so gut wie gar nichts.

Alternative 2
Delphi-Quellcode:
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;
Der Vollständigkeit wegen Dein Vorschlag
Delphi-Quellcode:
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;
Und mit folgender Prozedur hab ich die Zeiten gemessen.
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;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#57

Re: Function für Vorzeichen?

  Alt 10. Sep 2006, 12:43
Normalerweise hätte ich das mit Assembler gemacht, aber ich kenne mich dafür noch nicht gut genug mit der FPU aus.
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 6   « Erste     456   


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 03: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