Einzelnen Beitrag anzeigen

jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#11

Re: [Assembler]: 2 Variabeln austauschen

  Alt 11. Aug 2006, 00:42
Zitat von NamenLozer:
Öhm, was bewirkt eigentlich Inline?
Es bewirkt, dass der Compiler statt eines Funktionsaufrufes gleich die ganze Funktion an der Aufrufstelle einfügt.

Zitat:
Kann man das bei jeder Methode verwenden?
Können schon, nur ist der Compiler etwas wählerisch. Und wenn man alles als Inline deklariert, hast du am Schluss (theoretisch) Code produziert, bei dem jeder Funktion zig tausendfach vorhanden ist. Über die Exe-Dateigröße will ich da erst gar nicht nachdenken. Das aber nur theoretisch, weil der Compiler nicht alles inlinen kann/will.

Zitat:
Bringt es bei jeder Methode inen Geschwindigkeits-Boost?
Nein. Es kann sogar den gegenteiligen Effekt haben, weil dem Register-Allocator die freien Register ausgehen und der Compiler dann Code generiert der nur noch mit push und pop beschäftigt ist. Ruft man hingegen eine Funktion auf, so stehen dem Register-Allocator wieder alle Register zur Verfügung.

Hier mal ein Auszug aus meinem Code aus den Indy-Komponentnen (IdGlobal.pas). Würden die lokalen Find() und FindNext() ge-inlined wäre der Code um ein ganzes Stück langsamer, weil der Compiler das ESI Register im Inline-Code nicht verweden kann und somit bei jedem Schleifendurchlauf den PChar-Zeiger neu aus dem Speicher einliest und danach wieder dorthin schreibt (2 Speicherzugriffe mehr pro Schleifendurchlauf).
Delphi-Quellcode:
function PosIdx(const ASubStr, AStr: AnsiString; AStartPos: Cardinal): Cardinal;

  // use best register allocation on Win32
  function Find(AStartPos, EndPos: Cardinal; StartChar: AnsiChar; const AStr: AnsiString): Cardinal;
  begin
    for Result := AStartPos to EndPos do
      if AStr[Result] = StartChar then
        Exit;
    Result := 0;
  end;

  // use best register allocation on Win32
  function FindNext(AStartPos, EndPos: Cardinal; const AStr, ASubStr: AnsiString): Cardinal;
  begin
    for Result := AStartPos + 1 to EndPos do
      if AStr[Result] <> ASubStr[Result - AStartPos + 1] then
        Exit;
    Result := 0;
  end;

var
  StartChar: AnsiChar;
  LenSubStr, LenStr: Cardinal;
  EndPos: Cardinal;
begin
  if AStartPos = 0 then
    AStartPos := 1;
  Result := 0;
  LenSubStr := Length(ASubStr);
  LenStr := Length(AStr);
  if (LenSubStr = 0) or (AStr = '') or (LenSubStr > LenStr - (AStartPos - 1)) then
    Exit;

  StartChar := ASubStr[1];
  EndPos := LenStr - LenSubStr + 1;
  if LenSubStr = 1 then
    Result := Find(AStartPos, EndPos, StartChar, AStr)
  else
  begin
    repeat
      Result := Find(AStartPos, EndPos, StartChar, AStr);
      if Result = 0 then
        Break;
      AStartPos := Result;
      Result := FindNext(Result, AStartPos + LenSubStr - 1, AStr, ASubStr);
      if Result = 0 then
      begin
        Result := AStartPos;
        Exit;
      end
      else
        Inc(AStartPos);
    until False;
  end;
end;
  Mit Zitat antworten Zitat