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:

    1program InlineTest;
    2{$APPTYPE CONSOLE}
    3{$O+}
    4uses
    5  SysUtils;
    6
    7var
    8  s : string;
    9begin
   10  s:= 'Test';
   11  writeln(s);
   12  writeln(Length(s));
   13end.

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

    1function        _LStrLen{str: AnsiString}: Longint;
    2asm
    3        { ->    EAX str }
    4
    5        TEST    EAX,EAX
    6        JE      @@done
    7        MOV     EAX,[EAX-skew].StrRec.length;
    8@@done:
    9end;

Pro Delphi XE je to

    1function _UStrLen(const S: UnicodeString): Integer;
    2{$IF defined(CPUX64)}
    3begin
    4  Result := 0;
    5  if Pointer(S) <> nil then                // PStrRec should be used here, but
    6    Result := PLongInt(NativeInt(S) - 4)^; // a private symbol can't be inlined
    7end;
    8{$ELSE}
    9begin
   10  Result := Longint(S);
   11  if Result <> 0 then                // PStrRec should be used here, but
   12    Result := PLongint(Result - 4)^; // a private symbol can't be inlined
   13end;
   14{$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)

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

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 :-)


Nabízíme Delphi školení a konzultace na různá témata, primárně ve Vaší firmě.

Tagy: , ,

Optimalizace

Komentování ukončeno

Naše nabídka

Partial English version.

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 nebo burzy práce).

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 (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

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.

Anketa

Poslední komentáře

Comment RSS