2009-11-28 12 views
5

Qual è il problema con inlining le funzioni o le procedure in Delphi (in particolare la v2010, ma ho riscontrato lo stesso problema con Turbo Delphi)?Delphi 2010 inlining inutile?

C'è qualche disallineamento nell'aiuto su di esso potrebbe non essere sempre in linea una funzione a causa di "determinati criteri" qualunque cosa significhi.

Ma ho trovato che le funzioni generalmente inlining (anche quelle molto semplici che hanno 3 o 4 linee di codice) rallentano il codice piuttosto che lo accelera.

Un'ottima idea sarebbe l'opzione del compilatore per "incorporare tutto". Non mi interessa se il mio exe cresce del 50% circa per farlo funzionare più velocemente.

C'è un modo per forzare Delphi a codice realmente in linea anche se non è stato deciso di essere inserito dal compilatore? Questo sarebbe davvero d'aiuto. Altrimenti devi fare "inlining manuale" per replicare il codice di procedura in più aree del tuo codice con commenti come "// inlining fallito qui, quindi se cambi le 5 linee successive, cambiale negli altri 8 punti duplicati questo codice esiste "

Qualche consiglio qui?

risposta

11

C'è un'opzione del compilatore per l'inlining automatico di routine brevi. In Opzioni progetto, in Delphi Compiler -> Compilazione -> Generazione codice, attivare "Controllo inclinazione codice" su Auto. Si noti, tuttavia, che questo dovrebbe essere solo su una build di rilascio, poiché il codice inline è difficile da eseguire il debug.

Inoltre, hai detto che non ti dispiace rendere il tuo programma più lungo purché sia ​​più veloce, ma che spesso l'inlining lo rende più lento. Dovresti essere consapevole che ciò potrebbe essere correlato. Più grande è il tuo codice compilato, più mancano le cache di istruzioni che avrai, il che rallenta l'esecuzione.

Se si desidera accelerare il programma, eseguirlo tramite un profiler. Raccomando Sampling Profiler, che è gratuito, è fatto per funzionare con il codice Delphi (incluso il 2010) e non rallenta l'esecuzione. Ti mostrerà un rapporto dettagliato sul codice che stai effettivamente impiegando per la maggior parte del tempo. Una volta che lo hai trovato, puoi concentrarti sui colli di bottiglia e cercare di ottimizzarli.

+1

Il controllo di inlining del codice impostato su auto non ha aiutato. Il profilo di campionamento è eccezionale. Molto utile nel mostrare dove i colli di bottiglia sono in vere statistiche. Anche se davvero mi ha mostrato quello che già ero nuovo. Sarà di sicuro utile in futuro. Grazie. – TallGuy

3

Inlining può rendere le cose più lente in alcuni casi. La funzione inline può aumentare il numero di registri CPU richiesti per le variabili locali. Se non ci sono abbastanza registri, le variabili disponibili saranno invece memorizzate, il che lo rende più lento.

Se la funzione non è in linea avrà (quasi) tutti i registri della CPU disponibili.

Ho scoperto che di solito non è una buona idea integrare funzioni contenenti loop. Utilizzeranno un paio di variabili che probabilmente finiranno nella memoria, rendendo più lento il codice inline.

+2

Aumentando il numero di byte richiesti per eseguire un determinato algoritmo, si utilizzerà anche più la cache della CPU. In rari casi questo potrebbe anche avere un effetto. –

+3

Lars +1 - tranne che non è così raro. –

1

Se si desidera forzare inline quindi utilizzare include file. Devi assicurarti di dichiarare le variabili corrette e quindi utilizzare {$ I nomefile.inc}. Ciò inietterà sempre quel codice specifico esattamente dove lo vuoi, e renderà più facile mantenere se hai bisogno di cambiarlo.

Ricordare che il compilatore è scritto da persone molto più intelligenti della maggior parte dei mortali (incluso me stesso) e ha accesso a più informazioni al momento di decidere in linea o meno, quindi quando non è in linea probabilmente ha una buona ragione .

0

Se ho compreso correttamente uno dei devil del compilatore FPC (che ha lo stesso problema), l'inlining può avvenire solo quando la routine da inline è già stata compilata.

IOW se si effettua l'unità con l'unità "foglia" inline-to-be funzioni, e metterlo come prima nella clausola uses del progetto (.dpr), dovrebbe essere ok. Nota che con l'unità "leaf", intendo un'unità che non ha dipendenza da altre unità nel progetto, solo su unità già compilate.

Non sarei sorpreso che fosse lo stesso in Delphi, poiché condivide un sistema di unità basato sugli stessi principi.

È anche piuttosto non risolvibile senza violare principi di compilazione separati.