2016-04-28 4 views
11

[DCC32 Hinweis] H2443 Inline-Funktion 'RenameFile' hat nicht weil Einheit erweitert 'Winapi.Windows' angegeben ist nicht in VERWENDET ListeWarum ist Sysutils.RenameFile inline?

Ich verstehe, dass eine Funktion inlining schneller den Code macht. Aber ich sehe den Gewinn nur an engen Stellen. Zum Beispiel eine kleine Funktion in einer großen Schleife aufrufen.

Aber wie kann das Inlining einer IO-Funktion die Geschwindigkeit verbessern? Ich meine, durch das Einfügen von RenameFile gewinnen Sie einige Mikrosekunden. Aber die Ausführung der Funktion selbst kann Millisekunden, vielleicht sogar Dutzende von Millisekunden dauern, wenn der Datenträger ausgelastet ist.

Noch mehr, wenn Sie RenameFile verwenden, befinden Sie sich wahrscheinlich in einem Codeblock, in dem Sie andere E/A-Vorgänge ausführen. Dieser Codeblock wird also viel Zeit in Anspruch nehmen. Also ist der Gewinn jetzt noch unbedeutender.

+0

Aus dem gleichen Grund, dass sie ihren Parameter 'const' deklarierten ... ist der Leistungsgewinn vielleicht nicht so signifikant, aber er ist mehr oder weniger frei. (Wenn Sie nicht wüssten, deklarieren Sie einen String-Parameter 'const', entfernen Sie den Inc/dec seiner Referenzzählung, wenn er an eine Funktion übergeben wird). –

+1

@ KenBourassa-CONSTwird tatsächlich mehr als das und unter bestimmten Bedingungen (oft getroffen) ist der Geschwindigkeitsgewinn groß. – Ampere

+0

und was macht es sonst im Zusammenhang mit einem String?Für eine Aufzeichnung wird sie an Adresse weitergegeben, anstatt ihren Inhalt zu kopieren, also ja, sicher, der Geschwindigkeitsgewinn kann ziemlich groß sein. Aber im Zusammenhang mit einem String-Parameter ist die Referenzzahl (und alles, was damit zusammenhängt) der einzige Unterschied AFAIK. –

Antwort

17

RenameFile ist inline, weil es ein einfacher Aufruf an eine andere Funktion ist.

Hier ist, wie es aussieht:

function RenameFile(const OldName, NewName: string): Boolean; 
{$IFDEF MSWINDOWS} 
begin 
    Result := MoveFile(PChar(OldName), PChar(NewName)); 
end; 

Durch inlining diese Funktion der Aufruf an SysUtils.RenameFile durch einen Aufruf WinApi.Windows.MoveFile ersetzt wird.

Dies hat folgende Vorteile:

  • Sie einen Anruf speichern, statt zwei Anrufe, die Sie nur einen Anruf haben.
  • Ihr Telefoncode ist genau gleich groß.
  • Die CPU führt eine Liste von Rücksprungadressen für die Verzweigungsvorhersage (Rücksprungpuffer); Durch die Eliminierung des redundanten Aufrufs spart es Platz in diesem Puffer, was Fehlvorhersagen verhindert, wenn der Aufrufstapel zu tief wird. Der generierte Code ist kleiner, weil RenameFile selbst eliminiert wird.

So ist der inlining sehr viel der Mühe wert, vor allem in rekursiven Code, wo der Aufruf-Stack tief die CPU bekommen beginnt die Renditen mispredicting weil der Rückkehrstapelpufferüberlauf (einige CPUs haben nur 8 Einträge, Top die Linien-CPUs haben 24 Einträge).

In der Regel sollte jede Routine, die einfach eine andere Routine aufruft, immer inline sein.

Eine korrekt vorhergesagte Rücksendung kostet einen einzigen Zyklus, ein Fehlbericht entleert die Pipeline und kostet 25 Zyklen oder mehr; weitere Verzögerungen werden hinzugefügt, da die Rücksprungadresse aus dem Speicher und nicht aus dem Puffer abgerufen werden muss.

Sie haben Recht, dass keiner dieser Vorteile im Festplatten-IO-Code eine Rolle spielt, aber das ändert nichts an der Tatsache, dass einfache Weiterleitungsfunktionen wie diese immer inline sein sollten.

+0

Danke Johan. In diesem Fall habe ich wenige eigene Funktionen, die ich inline einbinden muss. – Ampere