2012-08-13 28 views
7

Nell'implementazione di un menu su un sistema incorporato in C (++) (AVR-Gcc), ho finito con un puntatore a funzione void che prendeva argomenti e di solito li usa.Quanto sono costosi gli argomenti del puntatore NULL?

// void function prototype 
void (*auxFunc)(char *); 

In alcuni casi (in realtà un bel po '), la funzione in realtà non ha bisogno l'argomento, quindi vorrei fare qualcosa di simile:

if (something) doAuxFunc(NULL); 

So che potrei solo ad un sovraccarico diverso tipo di funzione, ma in realtà sto cercando di non farlo mentre sto istanziando più oggetti e voglio tenerli leggeri.

È in corso la chiamata di più funzioni con puntatori NULL (quando sono destinati a un puntatore effettivo) peggiore rispetto all'implementazione di molti altri prototipi di funzioni?

+6

Che cosa dice il profiler? – zoul

+2

Perché pensi che i sovraccarichi siano "pesanti"? –

+0

@KerrekSB Principalmente perché ci saranno (relativamente) molti oggetti che li contengono e lo spazio è prezioso sui sistemi embedded. In questo caso un menu è più di una parte ausiliaria della funzionalità principale del progetto. – falro

risposta

9

Il controllo di NULL è un sovraccarico molto piccolo anche su un microcontrollore - il confronto con 0 dovrebbe essere velocissimo. Se sovraccarichi diverse funzioni, ti crucificherai la leggibilità per (un leggerissimo) miglioramento delle prestazioni. Lascia che l'ottimizzatore di GCC faccia tutto, è abbastanza buono :)

1

Penso che il "compromesso" sia ridicolmente basso per ogni approccio, ma questo è il momento di fare benchmark per te stesso. Se lo fai, per favore pubblica alcuni risultati :)

2

Il controllo di 0 è davvero economico, il sovraccarico è ancora più economico, poiché è deciso al momento della compilazione quale funzione scegliere.

Ma se si pensa che le proprie interfacce si complicano troppo con l'overloading e la propria funzione è piccola, è necessario dichiararlo inline e inserirlo in un'intestazione. Il check-in per 0 può quindi essere facilmente ottimizzato da qualsiasi compilatore moderno decente.

+0

Poiché questa è una soluzione per un sistema embedded, l'inlining comporterebbe l'utilizzo di più memoria di codice che è anche costosa in questo caso. – syplex

+0

@syplex: dipende molto dalla dimensione della chiamata alla funzione e dalla pulizia. Inlining può _save_ space.Questo è particolarmente vero quando un ragionevole ottimizzatore può eliminare le istruzioni non necessarie. Un semplice esempio comune è un metodo 'Foo :: getBar' che fornisce accesso in sola lettura al membro della barra in Foo. Questo potrebbe finire come un semplice calcolo dell'offset del puntatore e potrebbe persino essere piegato con altri calcoli di offset. – MSalters

+0

gcc ora ha la caratteristica di fare un inlining parziale. Fondamentalmente creerà un core di funzione in base a tutti i parametri e quindi incorpora la parte che può essere propagata costantemente. Questo non ha overhead di grandi dimensioni. –

3

Guardate allo smontaggio, dovrebbe generare un null (zero) da passare come primo argomento, che brucia un registro o una posizione di stack, se brucia un registro allora potrebbe costarvi un push e pop se la funzione chiamante sta morendo di fame per i registri. (il solo uso di una chiamata di funzione può costare spinte e pop se la funzione è affamata di registri per implementare la convenzione di chiamata).

Quindi è probabile che ci sia un costo, ma potrebbe non essere sufficiente un costo per cambiare il modo di fare le cose.