Optimiert(est)er peek für einen unsigned long 32bit

Für allgemeine Fragen zur Programmierung mit PureBasic.
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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');
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag von melow »

Christian... Danke! :allright:
Exakt was ich brauchte.

Ich nehm dann die ASM Variante.

Schöne Grüße
Melow :-)
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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]
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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 :-)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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.
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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 :-)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Optimiert(est)er peek für einen unsigned long 32bit

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten