2010-06-30 10 views
6

Actualmente tengo funciones en línea llamando a otra función en línea (una función simple de 4 líneas de getAbs()). Sin embargo, descubrí buscando en el código de ensamblador que las funciones en línea "grandes" están bien en línea, pero el compilador usa un salto bl para llamar a la función getAbs().en línea una función dentro de otra función en línea en C

¿No es posible alinear una función en otra función en línea? Por cierto, este es un código incrustado, no estamos utilizando las bibliotecas estándar.

Editar: El compilador es WindRiver, y ya he comprobado que la incorporación sería beneficiosa (4 instrucciones en lugar de + -40).

+0

¿Qué compilador estás usando? A menudo hay formas de forzar la alineación. Supongo que ya ha perfilado su código y está bastante seguro de que la inclusión será beneficiosa. En GCC, esto se puede hacer con __attribute __ ((always_inline)). – stinky472

+0

¿Puedo preguntar por qué te importan las decisiones que ha tomado el compilador? ¿Ha perfilado el código y encontrado que la sobrecarga de esa instrucción de salto único está matando el rendimiento? – JeremyP

Respuesta

8

Dependiendo del compilador que esté utilizando, puede alentar al compilador a ser menos reacio a alinearse, p. Ej. con gcc puede usar __attribute__ ((always_inline)), con Intel ICC puede usar icc -inline-level=1 -inline-forceinline, y con gcc de Apple puede usar gcc -obey-inline.

7

La palabra clave inline es una sugerencia al compilador, nada más. Es libre de tomar esa sugerencia a bordo, ignorarla totalmente o incluso mentirle y decir que lo está haciendo mientras que realmente no lo es.

La única manera de forzar que el código esté en línea es, bueno, escribirlo en línea. Pero, incluso, entonces el compilador puede decidir que sabe mejor y decide pasarlo a otra función. Tiene mucho margen de maniobra para generar código ejecutable para su fuente particular, siempre que no modifique su semántica.

Los compiladores modernos son más que capaces de generar mejores códigos que la mayoría de los desarrolladores realizarían a mano en el ensamblaje. Creo que la palabra clave inline debe seguir la misma ruta que la palabra clave register.

Si ha visto la salida de gcc en su nivel de optimización insana, comprenderá por qué. Ha producido un código que no hubiera soñado posible, y eso me llevó mucho tiempo entender.

Por favor, revise this para ver qué optimizaciones tiene realmente el gcc, incluyendo muchas que contienen el texto "en línea" o "en línea".

+0

Me aventuraría a adivinar y decir que la palabra clave se agregó cuando la tarea de averiguar si la función podría incluirse era demasiado grande para el compilador (ya sea en cuanto a funcionalidad o tiempo), pero el compilador de hoy es probablemente capaces de resolver esto por sí mismos, incluso si la palabra clave en línea no está presente. Sólo una suposición sin embargo. –

+0

Diría que fue una suposición bastante segura. Ver mi actualización – paxdiablo

+0

¿GCC admite optimizaciones basadas en perfiles? Cuando no los usa, tiene mucho sentido hacer una indicación de gcc donde podría ser útil. Esto se basa en el conocimiento de si la función se llamará * lot * o no, algo que el compilador más inteligente todavía no puede decir. – Peaker

1

@gramm: Hay bastantes escenarios en los que inline no es necesariamente para su beneficio. La mayoría de los compiladores usan heurísticas muy avanzadas para determinar cuándo alinearse. Cuando se habla de línea, la idea más simple es confiar en el compilador para producir el código más rápido.

-1

Sugeriría que si su función getAbs() (suena como valor absoluto pero realmente debería mostrarnos el código con la pregunta ...) es de 4 líneas, entonces tiene optimizaciones mucho más grandes de las que preocuparse que si el código se inserta o no.

+0

O bien está diciendo que cualquier sobrecarga de llamar a una función es menos importante para las funciones cortas, o está diciendo que tener funciones cortas es generalmente algo malo, de cualquier forma se obtiene -1 –

+0

No, estoy diciendo que un la mala implementación de 'abs()' es un golpe de rendimiento mucho más grande que el compilador que no lo alinea. (Y, de hecho, el compilador puede estar haciendo lo correcto al no marcarlo). –

+0

Igual que Pete. Tener 50 instrucciones en lugar de 5 es una gran sobrecarga, y generalmente se nota cuando se usa en un bucle. No estoy seguro si estás acostumbrado a trabajar con microcontroladores. – gramm

0

Recientemente he tenido un problema muy similar, la lectura de esta publicación me ha dado una idea de moda. ¿Por qué no? Tener un analizador de código simple de precompilación (un registro simple que haga el trabajo) que analiza la llamada a la función para realmente colocar el código fuente en línea. use una etiqueta como/en línea// end_of_inline/para que pueda usar las características ide normales (si es o podría usar una ide. Incluir esto en su proceso de compilación, de esa manera también tiene la ventaja de legibilidad como eliminar la suposición de los compiladores de que usted es solo un desarrollador tan bueno como la mayoría y no entiende cuándo hacerlo en línea.

Sin embargo, antes de intentar esto, probablemente debería ir a través de las opciones de línea de comandos de los compiladores.

Cuestiones relacionadas