Ich optimiere gerade ein bisschen am Speed meines Hashtable-Includes und übersetzte einige Teile von Hand in Assembler da mir der PB - Compiler nicht genug optimiert. Nun hab ich aber irgendwie einen Fehler in meiner Übersetzung, sieht einer der ASM - Gurus wo ich danebenhaue, bzw. kenn jemand noch ein paar Tricks das ganze unter x64 zu beschleunigen?
So auf die Schnelle sehe ich erstmal, dass man /2 mittels shr 1 schneller darstellen kann, für *2 kann man shl 1 nehmen (obwohl ich nicht weiß, ob das schneller als add edi,edi ist). Außerdem ist inc/dec AFAIK langsamer als add 1/sub 1.
Das mit dem if < 0 funktioniert so nicht. Du müsstest da ein jns (statt jge) nehmen (and eax,eax ist nicht gleich cmp eax,0).
Wie genau du auf *hMap\mapsize zugreifst, kann ich jetzt auch nicht wirklich erkennen (denn in [p.v_mapsize] steht das eher nicht, würde ich behaupten)…
Insgesamt wüsste ich jetzt nicht, wo genau das Problem ist (außer den beiden genannten), ich kenne aber z. B. die Variablentypen nicht. Wenn das .i ist, dann müsste das auf x64 ja 64 Bit sein, also qword (und somit rax statt eax, etc.).
If Not hash >= 0
Goto EndOfIf ; überspringe den fall, dass hash < 0 ist
EndIf
Blabla
EndOfIf:
Btw.: Du hast da counter / 2 zweimal drin, mach das bitte nur einmal. Und das moduloergebnis wird ja nie negativ sofern hash und *hMap\Mapsize positiv sind.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Aber and eax,eax ist nicht cmp eax,0.
Und das jge macht er dort nur hin, nachdem er da ein cmp hatte, oder?
Wobei ich erstmal nachsehen müsste, ob jge nicht am Ende doch ein Alias für jns ist…
EDIT: Na ja, jge springt, wenn ZF=1 oder SF=OF. Da das OF hier wohl immer 0 ist (und das SF bei ZF=1 automatisch 1 ist), entspricht das wohl (in diesem Fall) einem jns.
Jop, das im oberen Compilerif ist der Orginalcode.
Wie ich hab counter/2 2 mal drin? ich rechne counter durch 2 (EAX durch ECX, das Ergebniss ist wieder in EAX) und multipliziere das ganze mit sich selbst (IMUL EAX, EAX) entspricht doch (counter/2)*(counter/2), oder? Das ist schon so gewollt :P
Das mit dem mapsize = *hMap\mapsize ist nur dazu da das ich auf den Wert in *hMap\mapsize zugreifen kann (dword[p.v_mapsize]), ich hab keinen Plan wie ich PB Strukturelemente in ASM direkt ansprechen kann, das klappt schon so.
cxAlex hat geschrieben:Jop, das im oberen Compilerif ist der Orginalcode.
Wie ich hab counter/2 2 mal drin? ich rechne counter durch 2 (EAX durch ECX, das Ergebniss ist wieder in EAX) und multipliziere das ganze mit sich selbst (IMUL EAX, EAX) entspricht doch (counter/2)*(counter/2), oder? Das ist schon so gewollt :P
Ja im oberen Code hast du es 2 mal drin. Und der ist ja der default-code momentan.
cxAlex hat geschrieben:Das mit dem mapsize = *hMap\mapsize ist nur dazu da das ich auf den Wert in *hMap\mapsize zugreifen kann (dword[p.v_mapsize]), ich hab keinen Plan wie ich PB Strukturelemente in ASM direkt ansprechen kann, das klappt schon so.
Mit einem Offset geht das. Aber dann musst du das jedes mal ändern, wenn du das Offset in der Struktur änderst.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.