Hi Homer
Based on your posted implementation, I rearranged some instructions and replaced others and got a speed boost of about 30% on my CPU
Regards,
Biterider
Based on your posted implementation, I rearranged some instructions and replaced others and got a speed boost of about 30% on my CPU
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
bin2dword proc pBuffer:Pointer
push ebx
xor eax, eax
xor edx, edx
mov ecx, ;pBuffer
lea ebx,
align @WordSize
@@:
mov dl, byte ptr
cmp edx, 0
jz @F
cmp edx, "b"
jz @F
cmp ecx, ebx
jz @F
and dl, 1
shl eax, 1
or eax, edx
inc ecx
jmp @B
@@:
pop ebx
ret 4
bin2dword endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Regards,
Biterider
And here's my version, that improves 47% over the previous on my Sempron:
It's just that it stops reading when eax becomes a 32-bit number (thus many trailing zeroes are skipped).
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
db 10 dup (90h)
bin2dword2 proc pBuffer
mov ecx,
xor eax,eax
align 16
again:
movzx edx,byte ptr
inc ecx
sub edx,48
cmp edx,1
ja done
shl eax,1
add eax,edx
jge again
done:
ret 4
bin2dword2 endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
It's just that it stops reading when eax becomes a 32-bit number (thus many trailing zeroes are skipped).
And the qword:
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
bin2qword proc pBuffer ; returns value in eax:edx
mov ecx,
push ebx
xor eax,eax
xor edx,edx
align 16
again:
movzx ebx,byte ptr
inc ecx
sub ebx,48
cmp ebx,1
ja done
add eax,eax
adc edx,edx
or eax,ebx
test edx,edx
jge again
done:
pop ebx
ret 4
bin2qword endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Hi
Ultranos code shows some very clever optimizations. However, using his code, tricking with the carry flag and unrolling it gives you another speed gain of 30 %.
Regards,
Biterider
Ultranos code shows some very clever optimizations. However, using his code, tricking with the carry flag and unrolling it gives you another speed gain of 30 %.
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
NextChar macro
movzx edx, byte ptr
inc ecx
sub edx, "0"
cmp edx, 1
ja @F
rcl eax, 1
endm
bin2dword3 proc pBuffer:Pointer
xor eax, eax
mov ecx,
not eax
repeat 32
NextChar
endm
@@:
not eax
ret 4
bin2dword3 endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Regards,
Biterider
Ok guys now its my turn, I haven't timed the proc and compared it to your results. But I don't think its as fast as yours anyway.
It will take a bin string of any length, up to 64 bits and greater than 0 bits in length.
It does'nt need a special terminator, ie - 0 or b.
It returns the values in EDX:EAX, while ECX returns a -1 if the string length is 0 or
>64.
A bin value sting of 32 bits or less returns a 0 in edx, and the value in eax.
A bin value string of greater than 32 bits, returns the high dword in edx, and the low
dword in eax.
Here is the code:
Comments welcome :)
Rags
It will take a bin string of any length, up to 64 bits and greater than 0 bits in length.
It does'nt need a special terminator, ie - 0 or b.
It returns the values in EDX:EAX, while ECX returns a -1 if the string length is 0 or
>64.
A bin value sting of 32 bits or less returns a 0 in edx, and the value in eax.
A bin value string of greater than 32 bits, returns the high dword in edx, and the low
dword in eax.
Here is the code:
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
Bin2Quad proc pBinString:dword
push esi
mov esi,
xor ecx, ecx
xor edx, edx
ImFeelingLoopy:
cmp byte ptr , '1' ; count the number of 1 or 0's in string
je CountIt
cmp byte ptr , '0'
jne IAmDoneCounting
CountIt:
add ecx, 1
jmp ImFeelingLoopy
IAmDoneCounting:
or ecx, ecx
jz NotValidBinStr
cmp ecx, 64
ja NotValidBinStr
DbgDec ecx
cmp ecx, 32
jbe DoDWord
DbgDec ecx
sub ecx, 32 ; get number of high dword bits to do
CheckHighBits:
jecxz ImaDoneCheckingtheHighBits
cmp byte ptr , '1' ; set the carry and rotate it in if a one, else
jne @F ; rotate in a zero
stc
jmp SetTheBit
@@:
clc
SetTheBit:
rcl edx, 1
sub ecx, 1
add esi, 1
jmp CheckHighBits
ImaDoneCheckingtheHighBits:
mov ecx, 32 ; must be a full 32 bit lo-dword, since we had a high dword
DoDWord:
xor eax, eax
CheckLowBits:
jecxz ImaDoneCheckingtheLowBits
cmp byte ptr , '1' ; set the carry and rotate it in if a one, else
jne @F ; rotate in a zero
stc
jmp SetTheBit2
@@:
clc
SetTheBit2:
rcl eax, 1
sub ecx, 1
add esi, 1
jmp CheckLowBits
NotValidBinStr:
mov ecx, -1 ; Bin string either too long or too short-
jmp @f ; ie: 0 bit length or >64 bit length
ImaDoneCheckingtheLowBits:
xor ecx, ecx
@@:
pop esi
ret 4
Bin2Quad endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Comments welcome :)
Rags
LOL I am glad we all had fun optimizing code that is called so rarely :)
Work continues on the grammar engine.
I am hardcoding the 'grammar used to describe grammars' - ie, I am writing code which recognizes and responds to the very finite language (that being my grammar config file format, which is plaintext based) used to define the behaviour of the interpreter by describing desirable input patterns and appropriate responses.
The RuleLearner class object is derived from StatementParser.
Its job is to read a grammar descriptor file, and build from it a set of Grammar Rules.
Grammar Rules are chains of Terminal and/or NonTerminal Nodes.
Each Node is a reference to either a plaintext Term (Terminal), or a reference to a Rule (NonTerminal). SELF-references are allowed!
For example, the following rule:
<args> ::= <arg> ',' <args> | <arg>
Look apon the Pipe character as being a delimiter of acceptable variants.
The example Rules says "ARGS is a set of comma-delimited arguments, or, just one argument".
Can you see that this Rule contains a reference to itself?
I am developing the code that performs a non-iterative walk to allow for this kind of pattern matching. For those who may not be aware, this self-referencing concept was developed by a mathematician called KLEENE.. its called a Kleene star (a reference to wildcard patternmatching), or a Kleene escape.
Work continues on the grammar engine.
I am hardcoding the 'grammar used to describe grammars' - ie, I am writing code which recognizes and responds to the very finite language (that being my grammar config file format, which is plaintext based) used to define the behaviour of the interpreter by describing desirable input patterns and appropriate responses.
The RuleLearner class object is derived from StatementParser.
Its job is to read a grammar descriptor file, and build from it a set of Grammar Rules.
Grammar Rules are chains of Terminal and/or NonTerminal Nodes.
Each Node is a reference to either a plaintext Term (Terminal), or a reference to a Rule (NonTerminal). SELF-references are allowed!
For example, the following rule:
<args> ::= <arg> ',' <args> | <arg>
Look apon the Pipe character as being a delimiter of acceptable variants.
The example Rules says "ARGS is a set of comma-delimited arguments, or, just one argument".
Can you see that this Rule contains a reference to itself?
I am developing the code that performs a non-iterative walk to allow for this kind of pattern matching. For those who may not be aware, this self-referencing concept was developed by a mathematician called KLEENE.. its called a Kleene star (a reference to wildcard patternmatching), or a Kleene escape.