check if data is zero, the fast way

Share your advanced PureBasic knowledge/code with the community.
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

check if data is zero, the fast way

Post by Thorium »

On the german forum someone requested a optimized procedure for checking if a data in memory contains only zeros for a collision detection.

So here is my variant of this procedure. It's optimized for small amounts of data. It uses SSE2 if data is 16 byte or bigger.

Returns #False if data contains only zeros, returns #True otherwise.

Code: Select all

Procedure NoneZero(*DestBufStart, DestBufSize.i)

  CompilerSelect #PB_Compiler_Processor
  
    CompilerCase #PB_Processor_x86

      !push edi
      !push ebx
      
      !mov edi,[p.p_DestBufStart+8]
    
      !mov edx,[p.v_DestBufSize+8]
      !mov ecx,edx
      !mov ebx,ecx
      !shr edx,4
      !and ecx,15
      !shr ecx,2
      !and ebx,3
    
      !test edx,edx
      !je NoneZero_FirstEnd
      !pxor xmm1,xmm1
      
      !align 4
      !NoneZero_FirstStart:
    
        !movdqu xmm0,[edi]
        !pcmpeqb xmm0,xmm1
        
        !add edi,16
      
        !pmovmskb eax,xmm0
        !cmp eax,$0000FFFF
        !jne NoneZero_EndTrueSse
      
      !dec edx
      !jne NoneZero_FirstStart
      
      !emms
      
      !align 4
      !NoneZero_FirstEnd:
      
      !test ecx,ecx
      !je NoneZero_SecondEnd
    
      !align 4
      !NoneZero_SecondStart:
      
        !mov eax,[edi]
        !test eax,eax
        !jne NoneZero_EndTrue
        
        !add edi,4
      
      !dec ecx
      !jne NoneZero_SecondStart
    
      !align 4
      !NoneZero_SecondEnd:
    
      !test ebx,ebx
      !je NoneZero_ThirdEnd
    
      !align 4
      !NoneZero_ThirdStart:
      
        !mov al,[edi]
        !test al,al
        !jne NoneZero_EndTrue
        
        !inc edi
      
      !dec ebx
      !jne NoneZero_ThirdStart
      
      !align 4
      !NoneZero_ThirdEnd:
      
      !pop ebx
      !pop edi
    
      ProcedureReturn #False
    
      !NoneZero_EndTrue:
      !pop ebx
      !pop edi
      
      ProcedureReturn #True
    
      !NoneZero_EndTrueSse:
      !pop ebx
      !pop edi
      !emms
      
      ProcedureReturn #True
 
    CompilerCase #PB_Processor_x64
 
      !push rdi
      !push rbx
      
      !mov rdi,[p.p_DestBufStart+16]
    
      !mov rdx,[p.v_DestBufSize+16]
      !mov rcx,rdx
      !mov rbx,rcx
      !shr rdx,4
      !and rcx,15
      !shr rcx,2
      !and rbx,3
    
      !test rdx,rdx
      !je NoneZero_FirstEnd
      !pxor xmm1,xmm1
      
      !align 8
      !NoneZero_FirstStart:
    
        !movdqu xmm0,[rdi]
        !pcmpeqb xmm0,xmm1
        
        !add rdi,16
      
        !pmovmskb eax,xmm0
        !cmp eax,$0000FFFF
        !jne NoneZero_EndTrueSse
      
      !dec rdx
      !jne NoneZero_FirstStart
      
      !emms
      
      !align 8
      !NoneZero_FirstEnd:
      
      !test rcx,rcx
      !je NoneZero_SecondEnd
    
      !align 8
      !NoneZero_SecondStart:
      
        !mov eax,[rdi]
        !test eax,eax
        !jne NoneZero_EndTrue
        
        !add rdi,4
      
      !dec rcx
      !jne NoneZero_SecondStart
    
      !align 8
      !NoneZero_SecondEnd:
    
      !test rbx,rbx
      !je NoneZero_ThirdEnd
    
      !align 8
      !NoneZero_ThirdStart:
      
        !mov al,[rdi]
        !test al,al
        !jne NoneZero_EndTrue
        
        !inc rdi
      
      !dec rbx
      !jne NoneZero_ThirdStart
      
      !align 8
      !NoneZero_ThirdEnd:
      
      !pop rbx
      !pop rdi
    
      ProcedureReturn #False
    
      !NoneZero_EndTrue:
      !pop rbx
      !pop rdi
      
      ProcedureReturn #True
    
      !NoneZero_EndTrueSse:
      !pop rbx
      !pop rdi
      !emms
      
      ProcedureReturn #True
 
  CompilerEndSelect

EndProcedure
Last edited by Thorium on Sat Nov 21, 2009 10:10 pm, edited 1 time in total.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: check if data is zero, the fast way

Post by Mistrel »

This is pretty nice. Does this work for 64-bit processors as well?
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: check if data is zero, the fast way

Post by Thorium »

Mistrel wrote:This is pretty nice. Does this work for 64-bit processors as well?
Just updated the code, now it works with x64. ^^
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: check if data is zero, the fast way

Post by Mistrel »

Thanks a bunch. :)
Post Reply