Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   XE2 Stringfunktion + ASM code : function CountString(...) (https://www.delphipraxis.net/163243-xe2-stringfunktion-asm-code-function-countstring.html)

bernhard_LA 21. Sep 2011 09:45


XE2 Stringfunktion + ASM code : function CountString(...)
 
unter http://www.delphipraxis.net/51284-te...n-zaehlen.html gibt es super schnelle String-Funktionen,
leider bei mir nicht mit Delphi XE2 compilierbar

a) um prinzpiell im x32 und x64 bit mode zu kompilieren müssten doch die $IFDEF Definition richtig sein?
b) keyword ASM erzeugt bei mir einen Fehler im x64 bit modus
c) unter x32 bekomme ich folgenden Fehler
[DCC Fehler] _faststrings.pas(1467): E2116 Ungültige Kombination von Opcode und Operanden (bei TEST &SubStr, &SubStr) ??


Delphi-Quellcode:
///
/// Counts number of substr in S
/// source: [url]http://www.delphipraxis.net/51284-teil-string-anderem-string-suchen-zaehlen.html[/url]
///
/// failure with XE2 compiler !!!
function CountString(Const substr, s: AnsiString): Word;
begin
{$IFDEF CPUX86}
    ASM
      PUSH ESI
      PUSH EDI
      PUSH EBX
      TEST &SubStr, &SubStr
      JE @Exit
      TEST &S, &S
      JE @Exit0
      MOV ESI, &SubStr
      MOV EDI, &S
      PUSH EDI
      MOV ECX, [EDI - 4]
      MOV EDX, [ESI - 4]
      DEC EDX
      JS @Fail
      XOR EAX, EAX
      MOV AL, [ESI]
      INC ESI
      SUB ECX, EDX
      JLE @Fail

      @Loop:
      REPNE SCASB
      JNE @Ready
      MOV EBX, ECX
      PUSH ESI
      PUSH EDI
      MOV ECX, EDX
      REPE CMPSB
      POP EDI
      POP ESI
      JNE @noInc
      CMP EAX, $FFFF0000
      JAE @Ready
      ADD EAX, $00010000
      @noInc:
      MOV ECX, EBX
      JMP @Loop

      @Fail:
      POP EDX

      @Exit0:
      XOR EAX, EAX
      JMP @Exit

      @Ready:
      POP EDX
      SHR EAX, 16

      @Exit:
      POP EBX
      POP EDI
      POP ESI
    end;
{$ENDIF CPUX86}
///   x64 bit code
{$IFDEF CPUX64}
       ///  ????

      asm



      end;
{$ENDIF CPUX64}
End;

himitsu 21. Sep 2011 09:56

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Ein paar [delphi]-Tags wären nicht schlech. :zwinker:

Delphi-Quellcode:
begin
...
ASM
Geht unter 64 Bit garnicht mehr, da es dort kein Inline-Assemler mehr gibt (in Delphi).
Prozeduren müssen entweder in Pascal oder Assembler geschrieben sein. (gemischt ist nicht mehr ... je Prozedur)

also entweder
Delphi-Quellcode:
function CountString(Const substr, s: WideString): Word;
{$IFDEF CPUX86}
asm
...
end;
{$ENDIF CPUX86}
{$IFDEF CPUX64}
asm
...
end;
{$ENDIF CPUX64}
oder
Delphi-Quellcode:
function CountString(Const substr, s: WideString): Word;
asm
{$IFDEF CPUX86}
...
{$ENDIF CPUX86}
{$IFDEF CPUX64}
...
{$ENDIF CPUX64}
end;

Du könntest dir die WideString-Varianten nehmen und müßtest unter Win64 die Register anpassen.
Unter 32 Bit lagen die ersten Parameter in EAX, EDX, ECX, welche aber bei 64 Bit nun anders vereilt sind. Irgenwo wurde das hier, in der DP, vor Kurzem mal erwähnt.

Für den Anfang also einfach nur die entsprechenden 32-Bit-Register der 64-Bit-Architektur verwenden.


Wenn ich mal die Zeit finde, läßt sich dann bestimmt noch einiges Optimieren. (mit MMX, SSE und Co.)

daywalker9 21. Sep 2011 11:06

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Zitat:

Zitat von himitsu (Beitrag 1125712)
Ein paar [delphi]-Tags wären nicht schlech. :zwinker:


Du könntest dir die WideString-Varianten nehmen und müßtest unter Win64 die Register anpassen.
Unter 32 Bit lagen die ersten Parameter in EAX, EDX, ECX, welche aber bei 64 Bit nun anders vereilt sind. Irgenwo wurde das hier, in der DP, vor Kurzem mal erwähnt.

Für den Anfang also einfach nur die entsprechenden 32-Bit-Register der 64-Bit-Architektur verwenden.


Wenn ich mal die Zeit finde, läßt sich dann bestimmt noch einiges Optimieren. (mit MMX, SSE und Co.)

ASM Parameter:

Zitat:

The first four parameters to inline assembler functions are passed via RCX, RDX, R8, and R9 respectively, except for floating-point arguments which use XMMO, XMM1, XMM2, XMM3. The math coprocessor is not normally used from x64 code. Registers used for function parameters can be modified freely.

jbg 21. Sep 2011 11:30

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Warum das ganze überhaupt in Assembler? Das (die Quelle) sieht mir so aus als ob da "Assembler ist immer schneller als Pascal Code" gedacht wurde. Und dann auch noch "repnz scasb", was zu 80386-er Zeiten "relativ" schnell war aber mittlerweile besser mit einer loop gemacht wird.

himitsu 21. Sep 2011 12:00

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Eine Nicht-Assmbler-Version könnte wohl so aussehn: (ungetestet)
Delphi-Quellcode:
function CountString(const SubStr, S: String): Integer;
var
  i: Integer;
begin
  Result := 0;
  i     := 0;
  while True do begin
    i := PosEx(SubStr, S, i + 1);
    if i = 0 then Exit;
    Inc(Result);
  end;
end;
eventuell auch so:
(weiß grade nicht, wie genau gezählt wurde ... ist/war CountString('xxx', 'xxxxxx') = 2 oder 4? )
Delphi-Quellcode:
function CountString(const SubStr, S: String): Integer;
var
  i: Integer;
begin
  Result := 0;
  i     := 1;
  while True do begin
    i := PosEx(SubStr, S, i);
    if i = 0 then Exit;
    Inc(i, Length(SubStr));
    Inc(Result);
  end;
end;

Medium 21. Sep 2011 14:12

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Himiiii! "while true" und "Exit" - wo komms du denn her? ;)

Delphi-Quellcode:
function CountString(const SubStr, S: String): Integer;
var
  i: Integer;
begin
  Result := 0;
  i := 0;
  repeat
    i := PosEx(SubStr, S, i + 1);
    if i > 0 then
      Inc(Result);
    // oder
    Inc(Result, IfThen(Result>0, 1, 0));
    // Könnte nur langsamer sein
  until i = 0;
end;

DeddyH 21. Sep 2011 14:14

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Müsste i nicht vor der Schleife mit 0 initialisiert werden?

Medium 21. Sep 2011 14:19

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Ups :)

himitsu 21. Sep 2011 15:07

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Einfacher/Optimierter Code?
Das True und den Jump-Befehl sollte Delphi auch noch wegoptimieren.

Das Exit ist eigentlich ein Break, aber da hier nichts mehr nach der Schleife kommt...

PS:
siehe FastMM, EurekaLog, GNU gettext, FastReport, PgDAC, TMS Workflow, SynEdit, JCL und Delphi VCL ... überall findet man
Delphi-Quellcode:
while true do
:stupid:

jaenicke 21. Sep 2011 15:56

AW: XE2 Stringfunktion + ASM code : function CountString(...)
 
Das ist zur Optimierung auch manchmal sinnvoll (wenn denn die Funktion wirklich so wichtig ist was die Geschwindigkeit angeht).

Aber das Exit in einer Zeile mit dem if zu verstecken ist richtig unsaubere Formatierung... Sorry, aber ist so...


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:18 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz