Seite 2 von 2

Verfasst: 03.03.2008 18:12
von PMV
warum rechnet er dann in seinem Beispiel mit -9999 bis +9999?
:?
Klar, weil er damit die Zahl hinter/unter dem Bruchstrich meint. :wink:

MFG PMV

Verfasst: 03.03.2008 18:24
von Franky
Edit:
Syntaxfehler im Deutschen, Division durch zweierpotenzen, nich mit ;)
Ich dachte, man verseht mich schon :(

So, nun zu kaerus frage und PMVs antwort

Richtig, PMV. Ich hatte die Methode von Kaeru schonmal als Optimierungsvorschlag im Englischen Board gepostet (bzw. Das ASM-Äquivalent dazu). Trond hat mich auf den Fehler aufmerksam gemacht und so hab ich denn erstmal ruhe gegeben. Aber da ich mir sicher war, dass man den wie ich finde etwas langsamen Code (besonders IDIV) optimieren kann, hab ich einfach mal nachgeschaut, wie sich diese Veränderung auswirkt. Und siehe da, während IDIV im negativen Bereich aufrundet (-23/8 wird zu -3), rundet SAR ab (-23/8 wird zu -4).

Meine Pointerei, wie du´s so schön nennst (Falls du die Labels meinst O_o), fragt nun ab:
1.) Is der zu dividierende Wert<0?
Wenn ja:
2.)Ist der Wert kein gradzahlig vielfaches des Teilers?
Wenn nein: +1 und alles ist geritzt.



Zum praktischen nutzen:
Nunja.
Wie gesagt, habe ich es im Englischen Forum als Feature-Request gepostet. Da ich den Code aber nicht in dem Forum vergammeln lassen wollte, dachte ich mir, hier kann man sowas auch gebrauchen.
Praktische Anwendung in dem Sinne sollte es vor allem im Bereich normaler ASM-Optimierung finden.
Aber wenn du es unbedingt in einem Normalen Code einsetzen willst, kannst du ja mit einem Macro arbeiten. Das ist zwar keine Native Syntax, aber es nutzt dann den Code.

Code: Alles auswählen

Macro Divide(erg,wert,LaufIndex)
!        MOV    ebx,dword [v_#wert]
!         SAR    ebx,3
!        MOV    dword [v_#erg],ebx
!         CMP    ebx,0
!         JNL l___div_end_#LaufIndex
!            SAL ebx,3
!           CMP dword[v_#wert],ebx
!            JE l___div_end_#LaufIndex
!               INC dword[v_#erg]
         __div_end_#LaufIndex:
EndMacro
Der Laufindex muss sein, da sonst die Labels doppelt benannt sind.



Falls du nun wirklich Pointer meinst: Das dient nur dazu, die Werte in einen Speicherbereich ein zu tragen, damit man nachher abfragen kann, ob zwischen der PB-Spezifischen und der Eigenen Division unterschiede auftreten ;) Hat mit der Optimierung nichts zu tun, daher kann es über die Compilerdirektiven auch ausgeklammert werden :wink: :(

Verfasst: 03.03.2008 18:53
von Kaeru Gaman
ach SO du meinst den zähler....
sorry, bin nich voll auf der höhe (schupfen, husten, kopf- und gliederschmerzen)
ja kla, das is mit bitshift schwieriger...


[EDITH]
hier ist der code für negative zahlen...
du machst ja auch ne fallunterscheidung, also darf ich das auch... ;)

Code: Alles auswählen

a = -1000
Debug Hex(a)
a ! $FFFFFFFF
Debug a
a +1
Debug a
a >> 3
Debug a
a -1
Debug a
a ! $FFFFFFFF
Debug a

Verfasst: 04.03.2008 18:36
von Helle
Mit den neuen Intel-Prozis (habe den Wolfdale E8400) ist das Verhältnis übrigens nicht so gravierend (nur 1,4-fach schneller). Aus dem Asm-Code ist vielleicht noch ein bisschen rauszukitzeln:

Code: Alles auswählen

!        MOV    ebx,dword [v_a] 
!         SAR    ebx,3 
!        MOV    dword [v_c],ebx 
;!         CMP    ebx,0 
;!         JNL l___div_end 
!jns l___div_end   ;nach SAR von negativer Zahl ist das Signum-Flag gesetzt, sonst nicht 
;!            SAL ebx,3 
;!           CMP dword[v_a],ebx 
;!            JE l___div_end 
!test dword [v_a],7  ;dies ist Wert für Shift 3, für allgemeine Anwendung wohl nicht so gut
!jz l___div_end
!               INC dword[v_c] 
         __div_end: 
Aber in Test-Schleifen schlagen mitunter ganz andere Sachen zu...

Gruß
Helle