Zur Optimierung von FindString hat die Optimierungsphase 1:
Code: Alles auswählen
Procedure.i FindStringOptimierung1(strIn.s)
Protected sString1.i, sString2.i, eString1.i, eString2.i , hString1.i,hString2.i,eEnd.i
Protected *z1.Byte, *z2.Byte
sString1 = g_gepackteQuellGroesse+1
sString2 = Len(strIn.s)+1
hString1 = *g_mem ;Ptr auf 2 GB festen Speicher
hString2 = @strIn
If sString2 > sString1 Or sString2 = 0
ProcedureReturn 0
Else
eString1 = hString1 + sString1 - 1
eString2 = hString2 + sString2 - 1
eEnd = eString1 - sString2 +1
For *z1 = hString1 To eEnd
*z2 = hString2
While *z1\b = *z2\b
*z1 + 1
*z2 + 1
If *z2 = eString2
ProcedureReturn *z1 - sString2 - hString1 + 2
EndIf
Wend
Next
EndIf
ProcedureReturn 0
EndProcedure
gebracht.
Da hier viele gute ASM-Kenner mitlesen:
Wie kann man mit tollen ASM-Befehlen wie
Code: Alles auswählen
mov edi, *g_mem
mov eal,strIn.s
mov ecx,g_gepackteQuellGroesse
cld
repne scasb ; oder gleich 8 Bytes??
jnz quit ???
Bitte nur 64 Bit, da ich den i7 voll auslasten möchte.
Oder noch schneller mit SSE4.2 Befehlen in Phase 3:
Code: Alles auswählen
; ecx = *g_mem, edx = @Suchstring
push esi
push edi
MovDqU xmm2, dqword[edx] ;load 16 bytes Suchstring (was,wenn nur 8?)
Pxor xmm3, xmm3
lea eax, [ecx - 16]
; finde ersten 16-byte Fragmente in *g_mem
STRSTR_MAIN_LOOP:
add eax, 16
PcmpIstrI xmm2, dqword[eax], EQUAL_ORDERED
ja STRSTR_MAIN_LOOP
jnc STRSTR_NOT_FOUND
add eax, ecx ; save mögliche Übereinstimmung start
mov edi, edx
mov esi, eax
sub edi, esi
sub esi, 16
; vergleiche die strings
@B:
add esi, 16
MovDqU xmm1, dqword[esi + edi]
; mask out invalid bytes in the *g_mem
PcmpIstrM xmm3, xmm1, EQUAL_EACH + NEGATIVE_POLARITY + BYTE_MASK
MovDqU xmm4, dqword[esi]
PAnd xmm4, xmm0
PcmpIstrI xmm1, xmm4, EQUAL_EACH + NEGATIVE_POLARITY
ja @B
jnc STRSTR_FOUND
; continue next byte
sub eax, 15
jmp STRSTR_MAIN_LOOP
STRSTR_NOT_FOUND:
xor eax, eax
STRSTR_FOUND:
pop edi
pop esi
ret