Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#27

Re: Schnellster Stringmatching-Algorithmus in ASM übersetzen

  Alt 6. Dez 2007, 14:16
Ich habe die Erstellung der Sprungtabelle mal nach außen verlagert (außerhalb der Zeitmessung). Das bringt nix.

Edit:
Einen kleinen Punkt bringt es die Anzahl der Sprünge pro Schleife möglichst auf 1 zu minimieren:
Delphi-Quellcode:
function QSString(const ssubstr,text:string):Integer;stdcall;
//Delphi fügt automatisch push ebp; mov ebp,esp; ein
asm
  push ebx //register retten
  push edi
  push esi

  mov eax,[ebp+8] //ssubbstr
  mov edx,[eax-4] //length(ssubstr)
  mov ebx,edx //ebx=length(ssubstr) (für später)
  sub edx,2 //edx=length(ssubstr)-2
  push edx //n2 = [ebp - 16] =length(ssubstr)-2
  movzx edx, byte ptr [eax]
  push edx //c1 = [ebp - 20] =ssubstr[1]
  movzx edx, byte ptr [eax+ebx-1]
  push edx //cp= [ebp - 24] =ssubstr[ length(ssubstr) ]


  mov cx,$0100 //array mit ebx=length(ssubstr)+1 füllen
  inc ebx
 @fillarray:
    push ebx
    dec cx
  jnz @fillarray
  dec ebx

  // For i := 0 To n-1 Do Skip[sSubStr[i]] := n - i;
  xor ecx,ecx
  mov edi,[ebp+8] //ssubstr
  push ebx //length(ssubstr) auf [esp] legen/retten
  mov esi,ebp
  sub esi,$41C //Zeiger auf Sprungtabelle
 @fillotherskip: //for i=ecx :=0 to ebx
    movzx eax, byte ptr [edi+ecx] //ssubstr[ecx+1] in eax
    mov [esi+eax*4],ebx //[sprungtabelle+xxx] := length(ssubstr)-i
    inc ecx
    dec ebx
  jnz @fillotherskip


  mov esi,[ebp+12] //Zeiger auf text

  mov ecx,[esi-4] //length(text) in ecx
  sub ecx,[esp] //ecx ist jetzt k (length(ssubstr) abgezogen)
  jle @endwhile //wenn k<=0 Schleife überspringen

  xor edi,edi //Zählvariable
  mov bl,[ebp-20] //c1 und
  mov bh,[ebp-24] //cp
  mov edx,[esp] //Länge


  //in Schleife gilt:
  //edi ist Zähler i
  //esi ist Zeiger auf Text
  //ebx ist erster(bl) und letzter(bh) Char von substr
  //edx ist n (Länge von substr)
  //ecx ist k (Abbruchbedingung)



  sub ebp,$41C //ebp zeigt auf Sprungtabelle

  cmp [esi],bl //1. Vergleich c1 und text[1]
  jnz @endif //wenn ungleich --> springen
  mov eax,edx //length(ssubstr) in eax
  add eax,edi //i addieren
  cmp [esi+eax-1],bh //Vergleich text[i+length(ssubstr)] mit cp
  jnz @endifEx

 @while:



      cmp edx,3 //length(ssubstr) mit 3 vergleichen
      jl @positiveExit //wenn kleiner 3 dann Ergebnis gefunden

      //comparemem
      push ecx //register retten
      push edx
      push edi
      push esi
      mov ecx,[ebp+$40C] //length(ssubstr)-2
      mov edx,ecx
      and edx,3
      add esi,edi
      inc esi
      mov edi,[ebp+$424]
      inc edi
      shr ecx,2
      xor eax,eax
      repe cmpsd //Vergleich von DWORDs
      jne @endcmp
      mov ecx,edx
      repe cmpsb //Vergleich der restlichen Bytes
      jne @endcmp
      inc eax
     @endcmp:
      pop esi
      pop edi
      pop edx //register zurückholen
      pop ecx
      test al,al //Ergebnis von comparemem auswerten
      jnz @positiveExit

    //Der Block wird hauptsächlich durchlaufen und verursacht die benötigte Zeit
   @endif:
    mov eax,edx //length(ssubstr) nach eax
    add eax,edi //i dazuaddieren
   @endifEX:
    movzx eax, byte ptr [esi+eax] //test[i+length(ssubstr)+1]
    mov eax, [ebp+eax*4] //Wert aus Sprungtabelle
    add edi, eax //..zu i dazuaddieren
    cmp edi, ecx //mit k vergleichen
  jg @endwhile
    cmp [esi+edi],bl //Vergleich von text[i] mit c1
    jnz @endif

    mov eax,edx //length(ssubstr) in eax
    add eax,edi //i addieren
    cmp [esi+eax-1],bh //Vergleich text[i+length(ssubstr)] mit cp
    jnz @endifEx
    jmp @while

 @endwhile:

  xor eax,eax //result:=0
  jmp @exit
@positiveExit:
  mov eax,edi //result:=i
  inc eax
@Exit:
  add ebp,$41C
  lea esp,ebp-12
  pop esi
  pop edi
  pop ebx
end;
Edit2: Immer noch kleine Veränderungen, aber der große Sprung wird es mit dem Algorithmus nicht mehr
Angehängte Dateien
Dateityp: zip qsstring_117.zip (5,2 KB, 27x aufgerufen)
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat