2011-10-06 9 views
7

Me pregunto si alguien conoce la lógica que generalmente utilizan los compiladores de C++ para decidir si alinean o no una función en la compilación (suponiendo que se haya solicitado inline).¿Cómo decide un compilador si vale la pena realizar o no mis funciones en línea?

¿Esto es público?

+0

Puede valer la pena mencionar si tiene un compilador particular en mente, ya que hay indicadores que puede usar para influir en las decisiones del compilador. – Tom

+0

Para el compilador de microsoft: http://stackoverflow.com/questions/1204975/does-the-compiler-decide-when-to-inline-my-functions-in-c/1204980#1204980 – Tom

+1

Si ha solicitado inline es no es uno de los factores más importantes. –

Respuesta

5

He dado una respuesta más completa in this other question. (? ¿Esto significa que voy senil)

Básicamente compiladores tienen heurstics basado en análisis de costos, citando a mí mismo

Si se piensa en procesos en línea, y sus consecuencias, se dará cuenta de que:

  • a evitar una llamada de función (con todo el ajuste de registro ahorro/cuadro)
  • se expone más contexto para el optimizador (tiendas muertos, código muerto, común elimintation sub-expresión ...)
  • a costa de la duplicación de código (hinchazón de la caché de instrucciones y el tamaño del ejecutable, entre otras cosas)

Y, por supuesto, también hay procesos en línea parcial en la que sólo una parte de la función es en línea, por lo general una líder if guardia como foo(T* t) { if (!t) { return; } <many many things> }.

+0

Gracias, aceptada porque la respuesta vinculada fue muy útil :) – Bant

3

Sí, este tipo de información es de conocimiento público. Especialmente porque hay toneladas de compiladores de código abierto.

Creo que el libro para leer es el Dragon Book. Ellos pasan por todo esto allí, ¿no?

Pero básicamente: una llamada a la función tiene un costo: configurar los registros, saltar, recoger los resultados. Esto se puede contar en ciclos. El cuerpo de la función también tiene un costo medido en ciclos. Compara los dos. Puntos extra para tener en cuenta la localidad de caché.

+3

Otro parámetro en la métrica de costo es el efecto de incriminar en el tamaño del ejecutable. Es particularmente importante en el dominio de los sistemas integrados. – otto

+0

Gracias chicos, me gusta pensar en el costo en términos de ciclos de reloj. – Bant

+1

Pero, como otros señalan, hay otros términos para pensar en el costo en. Espacio, por ejemplo. –

1

Creo que los compiladores usan algún tipo de heurística para decidir si alinean o no una función.

Si se llama a la función desde un solo lugar, al alinearla se pueden reducir algunas instrucciones y ciclos, mejorando el tamaño y la velocidad.

Si se trata de una función pequeña, la alineación puede hacer lo mismo.

Si la función se llama en un circuito cerrado muchas veces, la alineación puede mejorar el rendimiento.

Al mismo tiempo, la alineación puede dar como resultado un código más grande en general y también puede tener algunos efectos negativos en el rendimiento debido al almacenamiento en caché de más código.

Los compiladores intentan hacer elecciones óptimas, pero también deben tener en cuenta cosas como opciones de optimización configurables (el programador puede decir que prefiere la velocidad sobre el tamaño o el opuesto) y cuánto tiempo les tomaría para tomar estas decisiones y generar el código (no desea que el compilador optimice mucho todo y tome muchas horas o días adicionales para compilar su código). Hay compensaciones.

Además, los compiladores no son todopoderosos.Simplemente no pueden juntar ciertos pares de personas, no porque sea caro, sino porque es casi imposible. Esta es la razón por la que hacemos pruebas de rendimiento y carga, tenemos perfiladores y hacemos que los humanos escriban código porque los humanos todavía son generalmente más inteligentes que sus programas.

+0

Deberías intentar hacer algunos párrafos ... Con respecto al reclamo de * solo una vez *, sí, definitivamente es un factor. Sin embargo, incluso una función 'estática 'llamada una vez puede no estar en línea. Al inclinarlo, puede aumentar la presión sobre los registros. –

+0

@MatthieuM .: hice algunos párrafos para la facilidad de lectura, gracias. –

+0

¡Gracias, mucho más legible, +1! –

1

La heurística dependerá de las opciones que pase el compilador, y también dependerá del compilador. No hay una respuesta general. La mayoría de los compiladores de hoy tienen combinaciones de opciones donde alinearán nada. La mayoría también tiene una combinación de opciones donde lo que alinean dependerá de la salida del perfilador de ejecuciones anteriores del programa. De lo contrario: desde el punto de vista de la calidad de implementación, es razonable esperar que el compilador funciones en línea declaradas inline más agresivamente que las no declaradas inline. Y generalmente será que cuando la optimización más agresiva haya sido activada, alineará una función cuya definición no está presente en la unidad de traducción . Finalmente, ciertas cosas en la función pueden inhibir en línea: algunos compiladores pueden no incluir funciones recursivas en línea, por ejemplo (aunque g ++ sí, al menos en ciertos casos).