2012-08-13 15 views
7

Al implementar un menú en un sistema incrustado en C (++) (AVR-Gcc), terminé con un puntero de función nula que toma argumentos, y usualmente los uso.¿Qué tan costosos son los argumentos del puntero NULL?

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

En algunos casos (de hecho unos cuantos), la función en realidad no necesita el argumento, por lo que haría algo como:

if (something) doAuxFunc(NULL); 

Sé que sólo pudiera sobrecargar a una diferente tipo de función, pero en realidad estoy tratando de no hacer esto ya que estoy instanciando múltiples objetos y quiero mantenerlos a la ligera.

Llamar a varias funciones con punteros NULL (cuando están destinados a un puntero real) es peor que implementar muchos más prototipos de función?

+6

¿Qué dice el generador de perfiles? – zoul

+2

¿Por qué crees que las sobrecargas son "pesadas"? –

+0

@KerrekSB Principalmente porque habrá (relativamente) muchos objetos que los tendrán, y el espacio es valioso en los sistemas integrados. En este caso, un menú es más una parte auxiliar de la funcionalidad principal del proyecto. – falro

Respuesta

9

La comprobación de NULLs es una sobrecarga muy pequeña incluso en un microcontrolador; se supone que la comparación con 0 es muy rápida. Si sobrecarga varias funciones, crucificará la legibilidad por (muy leve) mejora en el rendimiento. Simplemente deja optimizador de GCC hacer sus cosas, es bastante bueno en ello :)

1

creo que el "equilibrio" es ridículamente bajo para cada enfoque, pero este es el momento de hacerlo por sí mismo los puntos de referencia. Si lo hace, publique algunos resultados :)

2

La comprobación de 0 es realmente barata, la sobrecarga es aún más barata, ya que se decide en tiempo de compilación qué función elegir.

Pero si cree que sus interfaces se vuelven demasiado complicadas con la sobrecarga y su función es pequeña, debe declararlo inline y colocarlo en un encabezado. Checkig para 0 puede ser fácilmente optimizado por cualquier compilador moderno decente.

+0

Como esta es una solución para un sistema integrado, la alineación daría como resultado que se use más memoria de código, lo que también es costoso en este caso. – syplex

+0

@syplex: Eso depende mucho del tamaño de la llamada a la función y la limpieza. Inline puede _save_ space.Este es especialmente el caso cuando un optimizador razonable puede eliminar las instrucciones innecesarias. Un ejemplo simple común es un método 'Foo :: getBar' que proporciona acceso de solo lectura al miembro de Bar en Foo. Esto puede terminar como un simple cálculo de desplazamiento del puntero, e incluso podría doblarse con otros cálculos de desplazamiento. – MSalters

+0

gcc ahora tiene la característica de hacer una alineación parcial. Básicamente, creará un núcleo funcional en función de todos los parámetros y luego incorporará la parte que se puede propagar de forma constante. Esto no tiene mucho sobrecarga de tamaño. –

3

Mire el desmontaje, debe generar un nulo (cero) para pasar como primer argumento, que quema un registro o una ubicación de pila, si quema un registro, puede costarle un empujón y explotar si la función de llamada está muriendo de hambre por los registros. (El uso de una llamada a función puede costar empujes y saltos si la función está muriendo de hambre para los registros a fin de implementar la convención de llamadas).

Por lo tanto, es probable que haya un costo, pero puede no ser suficiente para cambiar la forma de hacer las cosas.

Cuestiones relacionadas