Seite 1 von 5
Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 05:19
von melow
Hi Leute,
im Augenblick benütze ich folgende Peek's um aus 4 bytes in in$ (big endian byte Reihenfolge) einen 32bit unsigned long zu erhalten.
Code: Alles auswählen
in$ = "abcd"
N.q = (PeekA(@in$) << 24) + (PeekA(@in$ + 1) << 16) + (PeekA(@in$ + 2) << 8) + (PeekA(@in$ + 3))
Debug N
Kennt wer von Euch eine effizientere Möglichkeit N zu erhalten? Gerne auch ( kommentierter

) Inline ASM.
Dank Euch sehr.
Liebe Grüße
Melow
PS: Die Perl (und PHP) variante dazu wäre:
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 07:32
von Christian+
Also nur ein PeekL statt 4 mal PeekA ist schon viel schneller und kommt noch ohne Inline ASM aus:
Code: Alles auswählen
Procedure.q PeekBigEndianUnsignedLong(*Memory)
Protected Long.i = PeekL(*Memory)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
ProcedureReturn ((Long<<24) & $FF000000) | ((Long<<8) & $00FF0000) | ((Long>>8) & $0000FF00) | ((Long>>24) & $000000FF)
CompilerElse
Long = (Long<<24) | ((Long<<8) & $00FF0000) | ((Long>>8) & $0000FF00) | ((Long>>24) & $000000FF)
ProcedureReturn Long & $FFFFFFFF
CompilerEndIf
EndProcedure
Noch schneller geht es mit Inline ASM, da es dort mit BSWAP einen Befehl für die Big-Endian Umwandlung gibt.
Code: Alles auswählen
Procedure.q PeekBigEndianUnsignedLong(*Memory)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
!MOV rdx, [p.p_Memory]
!MOV eax, [rdx]
!BSWAP eax
ProcedureReturn
CompilerElse
Protected Quad.q
!MOV edx, [p.p_Memory]
!MOV eax, [edx]
!BSWAP eax
!MOV [p.v_Quad], eax
ProcedureReturn Quad
CompilerEndIf
EndProcedure
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 08:07
von melow
Christian... Danke!
Exakt was ich brauchte.
Ich nehm dann die ASM Variante.
Schöne Grüße
Melow

Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 09:38
von melow
Ahh... da fällt mir noch was ein... rein interessehalber.
Folgender PB Code:
Code: Alles auswählen
Ascii.a = 255
*pointer = AllocateMemory(1)
PokeA(*pointer, Ascii.a)
Was wäre hier eigentlich die Inline ASM Variante von:
Danke
[Edit.. sollte: PokeA lauten]
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 09:45
von STARGÅTE
Code: Alles auswählen
Define ascii.a = 17
Define *pointer = AllocateMemory(1)
!MOV al, [v_ascii]
!MOV ecx, [p_pointer]
!MOV [ecx], al
Debug PeekA(*pointer)
Es wäre aber auch in PB einfacher:
Code: Alles auswählen
Define ascii.a = 17
Define *pointer.Ascii = AllocateMemory(1)
*pointer\a = ascii
Debug PeekA(*pointer)
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 13:41
von melow
STARGÅTE... Dir auch: Vielen herzlichen Dank!
Konnte mit Deiner und Christian's Inline ASM Hilfe meine Performancekritische Routine [eine Ascii85 Encodierung] um das ~30fache erhöhen. Spitze! [1MB Base85-Enkodieren: Vorher: ~9sek. Nacher: ~0,3sek.]
Wahrscheinlich ginge noch mehr... wenn ich in ASM fitter wäre. Aber für's erste bin ich damit schonmal zufrieden
@STARGÅTE: Ist Dein geposteter ASM Code x64 safe?
Da nun Blut geleckt

... würd ich mich gern in [F]ASM mehr einbarbeiten wollen in Verbindung mit PB.
So daß ich die Grundprinzipien (zB Schleifen, Bedingungen und mathematische Operationen) in Zukunft selbt machen kann.
Kann mir wer da eine gute Einstiegsdoku empfehlen? Wenn möglich mit PB Beispielen sogar.
Ach... nochwas @STARGÅTE:
Mein Pointer laute *o
aktzeptierte der PB Kompiler aber nicht. Symbol error.
Aber dafür ging dann:
Das gleiche mit:
Meine Varaible lautete [im produktiven Programmcode]: n
Bei
gab er mir aber dann auch ein Symbol error.
Mit:
gings dann.
Rätsel...:

... noch zumindest
Aber wie gesagt: Danke Euch!
Melow

Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 14:02
von STARGÅTE
@STARGÅTE: Ist Dein geposteter ASM Code x64 safe?
Nein, da der Pointer in ecx geschrieben wird, was immer 4Byte ist.
Unter x64 müsste es rcx heißen (8Byte). Wäre also ein Fall für CompilerIf
Kann mir wer da eine gute Einstiegsdoku empfehlen?
Wenn auch nicht vollständig, so benutze ich gerne diese Seite:
Assembler:Funktionen:Beschreibung-Lang-CPU
Mein Pointer laute *o [...] aktzeptierte der PB Kompiler aber nicht. Symbol error.
Das
p. bedeutet, dass die Variable aus der Procedure genommen werden soll (zB druch Protected definiert.)
Ohne, greift es auf globaldefinierte Namen zu.
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 14:02
von NicTheQuick
Das p. braucht man glaube ich, wenn es eine Variable in einer Procedure ist. Sozusagen kann man sich dann merken "p." = "protected". Ich denke ähnliches gibt es dann auch mit statischen Variablen und globalen Variablen.
Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 14:18
von melow
Ahh... p. für lokale Funktionsvariablen. ok. Alles klar. Rätsel gelöst. Danke Euch.
CompilerIf für x64 werd ich dann noch ergänzen. Danke. ecx = 4byte und rcx = 8byte register. ok. Gemerkt.
"Assembler:Funktionen:Beschreibung-Lang-CPU" Link gebookmark'ed. Sieht nach einen guten ASM Nachschlagewerk aus.
Wenn es Euch nicht nervt... eine kurze Frage hätte ich noch, angelehnt an obiges Beispiel:
Wie sähe in ASM folgender poke (für eine x86 CPU) aus:
Habs selbst (noch) nicht hinbekommen.
Schöne Grüße
Melow

Re: Optimiert(est)er peek für einen unsigned long 32bit
Verfasst: 02.09.2013 14:26
von STARGÅTE
Code: Alles auswählen
!MOV al, [v_ascii]
!MOV ecx, [p_pointer]
!MOV [ecx+1], al
Du kannst den Offset also direkt in die Adresse [ecx+1] schrieben.