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:

Code: Alles auswählen

print unpack('N', 'abcd');

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! :allright:
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:

Code: Alles auswählen

PokeA(*pointer, Ascii.a)
:roll:

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! :allright:

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

Code: Alles auswählen

!MOV ecx, [p_o]
aktzeptierte der PB Kompiler aber nicht. Symbol error.
Aber dafür ging dann:

Code: Alles auswählen

!MOV ecx, [p.p_o]
Das gleiche mit:

Code: Alles auswählen

!MOV al, [v_ascii]
Meine Varaible lautete [im produktiven Programmcode]: n
Bei

Code: Alles auswählen

!MOV al, [v_n]
gab er mir aber dann auch ein Symbol error.
Mit:

Code: Alles auswählen

!MOV al, [p.v_n]
gings dann.

Rätsel...: :roll: ... 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:

Code: Alles auswählen

PokeA(*pointer + 1 , Ascii.a)
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.