Hash Functions

Bare metal programming in PureBasic, for experienced users
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Hash Functions

Post by jassing »

wilbert wrote: Tue Feb 28, 2012 6:09 pm While I was converting MurmurHash3, I noticed the FNV32a procedure can be made significantly faster.
First a remark, the return type of FNV32a should be a long instead of a quad.

Here's the improved FNV32a code

Code: Select all

Procedure.l FNV32a(*key, len.l)
Old thread, I know... X64
error wrote: purebasic.asm [167]:
MOV edx,qword [rsp+PS10+0]
processed: MOV edx,qword[rsp+PS10+0]
error: operand sizes do not match.
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Hash Functions

Post by infratec »

Ugly but working:

Code: Select all

Procedure.l FNV32a(*key, len.l)
  EnableASM
   CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    MOV edx, *key
  CompilerElse
    MOV rdx, *key
  CompilerEndIf
  MOV ecx, len
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !push ebx
  CompilerElse
    !push rbx
  CompilerEndIf
  !mov eax, 2166136261 
  !fnv32a_loop:
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !movzx ebx, byte [edx]
  CompilerElse
    !movzx ebx, byte [rdx]
  CompilerEndIf
  !xor eax, ebx
  !imul eax, 0x01000193
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !inc edx
  CompilerElse
    !inc rdx
  CompilerEndIf
  !dec ecx
  !jnz fnv32a_loop
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !pop ebx
  CompilerElse
    !pop rbx
  CompilerEndIf
  DisableASM
  ProcedureReturn
EndProcedure
Looks better:

Code: Select all

Procedure.l FNV32a(*key, len.l)
  EnableASM
   CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
     MOV edx, *key
     MOV ecx, len
     !push ebx
     !mov eax, 2166136261 
     !fnv32a_loop:
     !movzx ebx, byte [edx]
     !xor eax, ebx
     !imul eax, 0x01000193
     !inc edx
     !dec ecx
     !jnz fnv32a_loop
     !pop ebx
  CompilerElse
    MOV rdx, *key
    MOV ecx, len
    !push rbx
    !mov eax, 2166136261 
    !fnv32a_loop:
    !movzx ebx, byte [rdx]
    !xor eax, ebx
    !imul eax, 0x01000193
    !inc rdx
    !dec ecx
    !jnz fnv32a_loop
    !pop rbx
  CompilerEndIf
  DisableASM
  ProcedureReturn
EndProcedure
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Hash Functions

Post by wilbert »

Funny how coding styles can change.
Nowadays I would use a local label (starting with a .) and add/sub instead of inc/dec .

Code: Select all

Procedure.l FNV32a(*key, len.l)
  !mov ecx, [p.v_len]
  !mov eax, 2166136261 
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !mov edx, [p.p_key]
    !push ebx
    !.loop:
    !movzx ebx, byte [edx]
    !xor eax, ebx
    !imul eax, 0x01000193
    !add edx, 1
    !sub ecx, 1
    !jnz .loop
    !pop ebx
  CompilerElse
    !mov rdx, [p.p_key]
    !push rbx
    !.loop:
    !movzx ebx, byte [rdx]
    !xor eax, ebx
    !imul eax, 0x01000193
    !add rdx, 1
    !sub ecx, 1
    !jnz .loop
    !pop rbx
  CompilerEndIf
  ProcedureReturn
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply