Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Sysutils.RenameFile inlined?

Tags:

inline

delphi

[dcc32 Hint] H2443 Inline function 'RenameFile' has not been expanded because unit 'Winapi.Windows' is not specified in USES list

I understand that inlining a function makes the code faster. But I see the gain only in tight places. For example calling a small function in a big loop.

But how can inlining an IO function can improve speed? I mean by inlining RenameFile you gain few microseconds. But executing the function itself may take milliseconds, maybe even tens of ms if the disk is busy.

Even more, if you are using RenameFile, you are probably in a block of code where you are doing other I/O operations. So, this block of code will take a lot of time. So, the gain is even more insignificant now.

like image 691
Server Overflow Avatar asked Apr 28 '16 11:04

Server Overflow


1 Answers

RenameFile is inlined because it is a simple call to another function.

Here's what it looks like:

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

By inlining this function the call to SysUtils.RenameFile gets replaced by a call to WinApi.Windows.MoveFile.

This has the following advantages:

  • You save a call, instead of two calls you only have one call.
  • Your calling code is exactly the same size.
  • The CPU keeps a list of return addresses for branch prediction (return stack buffer); by eliminating the redundant call it saves space in this buffer this prevents misprediction if the call stack gets too deep.
  • The generated code is smaller, because RenameFile itself gets eliminated.

So the inlining is very much worth the trouble, especially in recursive code where the call stack can get deep the CPU will start mispredicting the returns because the return stack buffer overflows (some CPU's have only 8 entries, top of the line CPU's have 24 entries).

As a rule every routine that simply calls another routine should always be inlined.

A correctly predicted return costs a single cycle, a mispredict empties the pipeline and costs 25 cycles or more; further delays are added because the return address needs to be fetched from memory rather than the buffer.

You are correct that none of these advantages are going to matter in disk IO code, but that does not detract from the fact that simple redirect functions like this should always be inlined.

like image 186
Johan Avatar answered Sep 23 '22 19:09

Johan