Znovu inline optimalizace

vložil Radek Červinka 25. září 2010 00:12

Ještě malá poznámka k inline optimalizacím. Tentokrát na ni upozornil přímo Allen Bauer a dokud na ni neupozornil on, tak jsem si tuto souvislost neuvědomil.

Mějme následující kvalitní kód:

program InlineTest;
{$APPTYPE CONSOLE}
{$O+}
uses
  SysUtils;

var
  s : string;
begin
  s:= 'Test';
  writeln(s);
  writeln(Length(s));
end.

Interně kompilátor pro length volá "magic" funkci, v případě Delphi 5 je to _LStrLen v system.pas, v případě Delphi 2010 nebo XE (ale i předchozích) je to _UStrLen také v system.pas.

Pro Delphi 5 je to

function        _LStrLen{str: AnsiString}: Longint;
asm
        { ->    EAX str }

        TEST    EAX,EAX
        JE      @@done
        MOV     EAX,[EAX-skew].StrRec.length;
@@done:
end;

Pro Delphi XE je to

function _UStrLen(const S: UnicodeString): Integer;
{$IF defined(CPUX64)}
begin
  Result := 0;
  if Pointer(S) <> nil then                // PStrRec should be used here, but
    Result := PLongInt(NativeInt(S) - 4)^; // a private symbol can't be inlined
end;
{$ELSE}
begin
  Result := Longint(S);
  if Result <> 0 then                // PStrRec should be used here, but
    Result := PLongint(Result - 4)^; // a private symbol can't be inlined
end;
{$IFEND}

Hlavní rozdíl je v tom, že v Delphi 5 je to v assembleru, kdežto v Delphi XE je to v Pascalu. Myslel jsem si původně, že je to k vůli 64bit.

OK, takže implementace v Delphi 2007 (tj. neunicode verze s inline)

function _LStrLen(const S: AnsiString): Longint;
begin
  Result := Longint(S);
  if Result <> 0 then                // PStrRec should be used here, but
    Result := PLongint(Result - 4)^; // a private symbol can't be inlined
end;

Od Delphi 2007 jsou patřičné funkce označeny jako inline, tj. kompilátor může vynechat volání a kód začlenit přímo.

Delphi 5
004086F8 E8BFAEFFFF       call @Write0LString
004086FD E8C5BEFFFF       call @WriteLn
00408702 E8F99EFFFF       call @_IOTest
Project1.dpr.11: writeln(Length(s));
00408707 A100A64000       mov eax,[s]
0040870C E85FADFFFF       call @LStrLen
00408711 8BD0             mov edx,eax
00408713 A1EC924000       mov eax,[$004092ec]
00408718 E8BFA0FFFF       call @Write0Long
0040871D E8A5BEFFFF       call @WriteLn
00408722 E8D99EFFFF       call @_IOTest
Delphi XE bez inline
004111E0 E87B33FFFF       call @Write0UString
004111E5 E8EE33FFFF       call @WriteLn
004111EA E8012BFFFF       call @_IOTest
004111EF A1787E4100       mov eax,[$00417e78]
004111F4 E8774DFFFF       call @UStrLen
004111F9 8BD0             mov edx,eax
004111FB A1EC2C4100       mov eax,[$00412cec]
00411200 E80B33FFFF       call @Write0Long
00411205 E8CE33FFFF       call @WriteLn
0041120A E8E12AFFFF       call @_IOTest
Delphi XE s inline
004111E1 E87A33FFFF       call @Write0UString
004111E6 E8ED33FFFF       call @WriteLn
004111EB E8002BFFFF       call @_IOTest
004111F0 8B1D787E4100     mov ebx,[$00417e78]
004111F6 85DB             test ebx,ebx
004111F8 7405             jz $004111ff
004111FA 83EB04           sub ebx,$04
004111FD 8B1B             mov ebx,[ebx]
004111FF A1EC2C4100       mov eax,[$00412cec]
00411204 8BD3             mov edx,ebx
00411206 E80533FFFF       call @Write0Long
0041120B E8C833FFFF       call @WriteLn
00411210 E8DB2AFFFF       call @_IOTest

Tím, že inlinovaná funkce je psána přímo v Object Pascalu, je umožněno kompilátoru při inline optimalizaci používat i jiné registry, než by původně programátor zamýšlel. V případě, že by inline funkce byla psaná v assembleru (jako v Delphi 5), musel by kompilátor před voláním šachovat s registry, což určitě není optimální.

Závěr: pokud opravdu nemáte velký důvod pro assembler, tak to nedělejte :-)

Tagy: , ,

Optimalizace

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS