Mit SSE4.2 kann ich im englichen Forum wohl nicht punkten (läuft ja nicht auf 10 Jahre alten Notebooks ), deshalb hier für Win64 und Unicode Test-Codes jeweils für FindString und FindChar (also nur 1 Zeichen wird gesucht).
Code: Alles auswählen
String$ = Space(1000000) + "8!#"
FindString$ = "8!"
;FindString$ = " 8!" ;längeren FindString sollte man auch mal testen :-) !
FindChar$ = "!"
StartPos.q = 1;2345
#Loops = 1000
Procedure.q FindString_SSE42_64Bit_Uni(pString, pFindString, Start)
;hier mal testweise eingefügt
!cmp dword[PB_Compiler_Debugger],0 ;Debugger aus?
!je @f ;ja
;Debug "Mach aus das Ding!"
MessageRequester("Debugger", "Mach aus das Ding!")
!mov r8,[p.v_Start] ;für 32-Bit wäre dies (mit 32-Bit-Registern) notwendig
!mov rdx,[p.v_pFindString]
!mov rcx,[p.v_pString]
!@@:
!cmp r8,1 ;r8=StartPos
!jge @f
!mov r8,1 ;oder Ende oder Error (?)
!@@:
!mov rax,r8 ;rax=Rückgabe-Wert Pos
!dec r8
!shl r8,1
!mov r12,rcx ;rcx=pString, ecx wird aber von pcmpistri verwendet
!add r12,r8
!cmp word[rcx],0 ;Test auf Null-String hier mal eingefügt
!je .NoFound
!cmp word[rdx],0 ;rdx=pFindString
!je .NoFound
!movdqu xmm0,[rdx] ;ersten max.16 Bytes (8 Words) von FindString
!xor rcx,rcx
!.Search:
!add rax,rcx
!add r12,rcx
!add r12,rcx
!movdqu xmm2,[r12] ;wegen StartPos, 2.Parameter von pcmpistri muss align16 sein
!pcmpistri xmm0,xmm2,00001101b ;Least Significant Index, Positive Polarity (IntRes2=IntRes1), Equal Ordered, Unsigned Words (=Unicode)
!jno .Search
!js .Find$End
!jz .Base$End
!mov r9,r12
!mov r10,rdx
!@@:
!add r10,16 ;nächste 8 Words von FindString
!add r9,16 ;nächste 8 Words von String
!movdqu xmm1,[r10]
!movdqu xmm2,[r9]
!pcmpistri xmm1,xmm2,00001101b
!js .Find$End
!jz .Base$End
!jo @b
!jmp .Search
!.Base$End:
!cmp rcx,8
!je .NoFound
!jmp .Found
!.Find$End:
!or rcx,rcx ;rcx Zero?
!jne .Search
!.Found:
!add rax,rcx
ProcedureReturn ;rax
!.NoFound:
!xor rax,rax
ProcedureReturn ;rax
EndProcedure
Procedure.q FindCharSSE42_64Bit_Uni(pString, pFindChar, Start)
;hier mal testweise eingefügt
!cmp dword[PB_Compiler_Debugger],0 ;Debugger aus?
!je @f ;ja
;Debug "Mach aus das Ding!"
MessageRequester("Debugger", "Mach aus das Ding!")
!mov r8,[p.v_Start] ;für 32-Bit wäre dies (mit 32-Bit-Registern) notwendig
!mov rdx,[p.v_pFindString]
!mov rcx,[p.v_pString]
!@@:
!cmp r8,1 ;r8=StartPos
!jge @f
!mov r8,1 ;oder Ende oder Error (?)
!@@:
!mov rax, -16
!shl r8,1
!add rax,r8
!movdqu xmm1,[rdx] ;rdx=pFindChar
!mov r9,rcx ;rcx=pString, ecx wird aber von pcmpistri verwendet
!@@:
!add rax,16
!movdqu xmm0,[r9+rax] ;wegen StartPos, 2.Parameter von pcmpistri muss align16 sein
!pcmpistri xmm1,xmm0,00000001b ;Bit0 = 1 und Bit1 = 0, also String-Chars werden als unsigned Words (=Unicode) interpretiert, Bit2 = 0 und Bit3 = 0, also Test auf equal any
!ja @b ;C=0, Z=0
!cmp rcx,8
!je @f
!shr rax,1 ;Pointer in String muss hier halbiert werden
!add rax,rcx
!inc rax
ProcedureReturn ;rax = Pos., beginnt bei 1
!@@:
!xor rax,rax
ProcedureReturn ;rax = 0, Char nicht gefunden
EndProcedure
;PB
TA = ElapsedMilliseconds()
For i = 1 To #Loops
PosPB = FindString(String$, FindString$, StartPos)
Next
TE = ElapsedMilliseconds() - TA
PB$ = "PB : Time = " + Str(TE) + " ms Result : " + Str(PosPB)
;SSE4.2
TA = ElapsedMilliseconds()
For i = 1 To #Loops
PosSSE = FindString_SSE42_64Bit_Uni(@String$, @FindString$, StartPos)
Next
TE = ElapsedMilliseconds() - TA
FindString_SSE42_64Bit_Uni$ = "SSE4.2 : Time = " + Str(TE) + " ms Result : " + Str(PosSSE)
MessageRequester("FindString 64-Bit Unicode", PB$ + #CRLF$ + FindString_SSE42_64Bit_Uni$)
;PB
TA = ElapsedMilliseconds()
For i = 1 To #Loops
PosPB = FindString(String$, FindChar$, StartPos)
Next
TE = ElapsedMilliseconds() - TA
PB$ = "PB : Time = " + Str(TE) + " ms Result : " + Str(PosPB)
;SSE4.2
TA = ElapsedMilliseconds()
For i = 1 To #Loops
PosSSE = FindCharSSE42_64Bit_Uni(@String$, @FindChar$, StartPos)
Next
TE = ElapsedMilliseconds() - TA
FindChar_SSE42_64Bit_Uni$ = "SSE4.2 : Time = " + Str(TE) + " ms Result : " + Str(PosSSE)
MessageRequester("FindChar 64-Bit Unicode", PB$ + #CRLF$ + FindChar_SSE42_64Bit_Uni$)
Ist aber noch nicht ganz durchgetestet!