2016-04-28 24 views
11

[dcc32 Suggerimento] funzione H2443 Inline 'RenameFile' non è stato ampliato perché unita 'Winapi.Windows' non è specificato nella lista USIPerché Sysutils.RenameFile è in linea?

Capisco che inlining una funzione rende il codice più veloce. Ma vedo il guadagno solo in spazi ristretti. Ad esempio chiamando una piccola funzione in un grande ciclo.

Ma come è possibile migliorare la velocità con una funzione di I/O? Intendo, richiamando RenameFile guadagni qualche microsecondo. Ma l'esecuzione della funzione stessa può richiedere millisecondi, forse anche decine di ms se il disco è occupato.

Ancora di più, se si utilizza RenameFile, si è probabilmente in un blocco di codice in cui si stanno eseguendo altre operazioni di I/O. Quindi, questo blocco di codice impiegherà molto tempo. Quindi, il guadagno è ancora più insignificante adesso.

+0

Per lo stesso motivo hanno dichiarato il suo parametro 'const' ... il guadagno di prestazioni potrebbe non essere così significativo, ma è più o meno libero. (Se non lo sapessi, dichiarando un parametro stringa 'const' rimuovi Inc/dec dal suo conteggio di riferimento quando viene passato a una funzione). –

+1

@ KenBourassa-CONSTactually fa più di quello ed in determinate condizioni (incontrate abbastanza spesso) il guadagno di velocità è grande. – Ampere

+0

e che altro fa nel contesto di una stringa?Per un record, sarà passato per indirizzo invece di copiare il suo contenuto quindi sì, certo, il guadagno di velocità può essere piuttosto grande. Ma nel contesto di un parametro stringa, il conteggio dei riferimenti (e tutto ciò che è relativo) è l'unica differenza AFAIK. –

risposta

17

RenameFile è in linea perché è una semplice chiamata a un'altra funzione.

Ecco come si presenta:

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

Con questa funzione inlining la chiamata a SysUtils.RenameFile viene sostituito da una chiamata a WinApi.Windows.MoveFile.

Questo ha i seguenti vantaggi:

  • si salva una chiamata, invece di due chiamate Hai solo una chiamata.
  • Il codice di chiamata è esattamente della stessa dimensione.
  • La CPU conserva un elenco di indirizzi di ritorno per la previsione ramo (buffer stack di restituzione); eliminando la chiamata ridondante, si risparmia spazio in questo buffer e questo impedisce una cattiva previsione se lo stack delle chiamate diventa troppo profondo.
  • Il codice generato è più piccolo, perché lo stesso RenameFile viene eliminato.

Quindi la messa in linea è molto vale la pena, soprattutto nel codice ricorsivo in cui lo stack di chiamata può arrivare in profondità la CPU inizierà mispredicting i ritorni a causa di overflow del buffer di stack di ritorno (un po 'di CPU hanno solo 8 voci, cima le CPU della linea hanno 24 voci).

Di norma, ogni routine che chiama semplicemente un'altra routine deve essere sempre in linea.

Un ritorno correttamente previsto costa un singolo ciclo, un errore scorretto svuota la pipeline e costa 25 cicli o più; ulteriori ritardi vengono aggiunti perché l'indirizzo di ritorno deve essere recuperato dalla memoria anziché dal buffer.

È corretto che nessuno di questi vantaggi avrà importanza nel codice IO del disco, ma ciò non toglie che le semplici funzioni di reindirizzamento come questa dovrebbero essere sempre sottolineate.

+0

Grazie Johan. In questo caso ho poche funzioni personali che devo allineare. – Ampere