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

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

Posted on 2007-10-06 00:19:33 by Biterider
And here's my version, that improves 47% over the previous on my Sempron:

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).
Posted on 2007-10-06 04:40:36 by Ultrano
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
Posted on 2007-10-06 05:23:36 by Ultrano
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 %.

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
Posted on 2007-10-06 09:52:03 by 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:

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
Posted on 2007-10-06 19:19:03 by 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.


Posted on 2007-10-09 02:19:42 by Homer