Page 2 of 2

Re: Hash Functions

Posted: Thu May 30, 2024 8:21 pm
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.

Re: Hash Functions

Posted: Thu May 30, 2024 10:13 pm
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

Re: Hash Functions

Posted: Fri May 31, 2024 6:13 am
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